线程安全智能指针实现(引用计数)

   线程安全指针实现如下:

  

#ifndef INTELLECT_PTR_H
#define INTELLECT_PTR_H
#include 
#include 

template 
class interllect_ptr
{
public:
    interllect_ptr()
    {
        if (_p == nullptr)
        {
            _p = new PTR();
            ++_count;
        }
    }

    ~interllect_ptr()
    {
        --_count;
        if (_count == 0)
        {
            delete _p;
            _p = nullptr;
        }
    }

    interllect_ptr(const interllect_ptr& ptr)
    {
        if (this != &ptr)
        {
            _p = ptr._p;
            _count =  ptr._count.load(std::memory_order_seq_cst); // 可疑代码段,不安全根源
            ++_count;
        }

    }

    interllect_ptr& operator= (const interllect_ptr &ptr)
    {
        if (this == ptr)
        {
            return *this;
        }

        if (_p != nullptr)
        {
            this->~interllect_ptr();
        }

        _count = ptr._count.load(std::memory_order_seq_cst);
        _p = ptr._p;
        ++_count;

        return *this;
    }

    PTR& get_value()
    {
        assert(this->_p != nullptr);
        return *(this->_p);
    }

    PTR* get_value_ptr()
    {
        assert(this->_p != nullptr);
        return this->_p;
    }

private:
    std::atomic _count;
    PTR *_p;
};

#endif // !INTELLECT_PTR_H

 测试代码如下:

#ifndef INTELLECT_PTR_TEST_H
#define INTELLECT_PTR_TEST_H
#include 
#include 
#include 
#include 
#include "intellect_ptr.h"

std::atomic create = 0;
std::atomic del_count = 0;
struct test_value
{
    test_value()
    {
        std::cout << "test_value()" << std::endl;
        ++create;
        _count = 0;
    }

    ~test_value()
    {
        ++del_count;
        std::cout << "~test_value()" << std::endl;
    }

    test_value(const test_value &t)
    {
        std::cout << "test_value(const test_value &t)" << std::endl;
    }

    test_value& operator= (const test_value &t)
    {
        std::cout << "test_value& operator= (const test_value &t)" << std::endl;
    }

    int _count;
};

void copy_share_ptr(interllect_ptr share_ptr, interllect_ptr copy_share_ptr)
{
    copy_share_ptr = share_ptr;
    test_value &value = copy_share_ptr.get_value();
    value._count++;
}

void thread_fun(interllect_ptr share_ptr)
{
    interllect_ptr copy_share_ptr1;
    test_value &value = share_ptr.get_value();

    for (int i = 0; i < 100; i++)
    {
        test_value *p = share_ptr.get_value_ptr();
        copy_share_ptr(share_ptr, copy_share_ptr1);
        auto c = share_ptr;
    }
}

class intellect_ptr_test
{
public:
    void start_test()
    {
        {
            auto share_ptr = interllect_ptr();
            test_value &i = share_ptr.get_value();
            test_value *p = share_ptr.get_value_ptr();

            int c = 0;
            while (c < 10)
            {
                std::vector vec_thread;
                for (int i = 0; i < 100; i++)
                {
                    vec_thread.push_back(std::thread(thread_fun, share_ptr));
                }

                for (std::thread &iter : vec_thread)
                {
                    iter.join();
                }
                c++;
            }
            std::cout << "结果:" << i._count;
        }

        std::cout << "创建:"<< create<< "销毁:"<< del_count<

    运行结果如下:

线程安全智能指针实现(引用计数)_第1张图片

     1、智能指针被复制到了每一个线程中,所有线程执行完成后,引用计数值为0,正确的释放了 test_value()对象

     2、唯一可能出问题的地方就在atomic对象拷贝时,atomic对象本来是不支持拷贝的,其定义如下:

          atomic operator = (const atomic &a) = delete;

    3、 这里采取了先load 被拷贝对象atomic对象,再将load取出的值赋给另外一个atomic对象,不知道是否会出问题,简单测试来说是看不出来的问题的。

    4、还有一点就是指针里的数据是不保证线程安全的,只是保证了指针正确释放的线程安全,也就是引用计数器的线程安全。

 

 

你可能感兴趣的:(c++编程)