1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| template <typename T> class ThreadSafePointer { public: ThreadSafePointer() : data(nullptr), ref_count(new size_t(0)), mutex(new std::mutex()) {}
ThreadSafePointer(T* ptr) : data(ptr), ref_count(new size_t(1)), mutex(new std::mutex()) {}
ThreadSafePointer(const ThreadSafePointer<T>& other) { std::lock_guard<std::mutex> lock(*other.mutex); data = other.data; ref_count = other.ref_count; (*ref_count)++; mutex = other.mutex; }
ThreadSafePointer& operator=(const ThreadSafePointer<T>& other) { if (this == &other) return *this;
release(); std::lock_guard<std::mutex> lock(*other.mutex); data = other.data; ref_count = other.ref_count; (*ref_count)++; mutex = other.mutex; return *this; }
~ThreadSafePointer() { release(); }
T* get() const { std::lock_guard<std::mutex> lock(*mutex); return data; }
size_t use_count() const { std::lock_guard<std::mutex> lock(*mutex); return *ref_count; }
private: T* data; size_t* ref_count; std::mutex* mutex;
void release() { std::lock_guard<std::mutex> lock(*mutex); if (ref_count && --(*ref_count) == 0) { delete data; delete ref_count; delete mutex; } } };
ThreadSafePointer<int> ptr1(new int(42)); { ThreadSafePointer<int> ptr2 = ptr1; std::cout << "ptr2: " << *ptr2.get() << " (use count: " << ptr2.use_count() << ")" << std::endl; }
std::cout << "ptr1: " << *ptr1.get() << " (use count: " << ptr1.use_count() << ")" << std::endl;
|
上面的代码实现了一个简单的线程安全智能指针 ThreadSafePointer
,它用于管理一个动态分配的对象(例如 int
)。以下是代码的原理解释:
类模板定义:
ThreadSafePointer
类是一个模板类,可以管理不同类型的动态分配对象。
成员变量:
data
:指向实际数据的指针。
ref_count
:一个指向引用计数的指针。引用计数表示有多少个智能指针共享相同的资源。
mutex
:一个互斥锁,用于保护 data
和 ref_count
的访问。
构造函数:
- 默认构造函数:初始化
data
为 nullptr
,ref_count
为 0,mutex
为一个新的互斥锁。
- 构造函数接受指向资源的原始指针,将
data
指向该资源,初始化 ref_count
为 1,创建一个新的互斥锁。
复制构造函数:
- 复制构造函数被用于创建一个新的
ThreadSafePointer
对象,该对象共享相同的资源。
- 它通过获取另一个智能指针的互斥锁来保证线程安全,并增加引用计数。
- 共享的
ref_count
和 mutex
在对象之间共享,以确保线程安全的引用计数。
赋值运算符重载:
- 赋值运算符用于将一个
ThreadSafePointer
对象赋值给另一个对象。
- 在这个实现中,首先释放调用对象的资源(如果有),然后像复制构造函数一样,共享另一个对象的资源。
析构函数:
- 析构函数用于释放资源。
- 它首先获取互斥锁以确保线程安全,然后检查引用计数。如果引用计数减为零,表示没有智能指针引用该资源,就释放资源并删除引用计数和互斥锁。
get
方法:
get
方法返回存储在 ThreadSafePointer
中的指向资源的原始指针。在获取指针时,它会获取互斥锁以确保线程安全。
use_count
方法:
use_count
方法返回当前资源的引用计数,以确定有多少个智能指针引用了该资源。同样,它也获取互斥锁以确保线程安全。
main
函数:
- 在
main
函数中,我们演示了如何创建和使用 ThreadSafePointer
对象来管理整数资源。创建一个 ThreadSafePointer
对象时,资源的引用计数初始化为 1。然后,通过复制构造函数创建第二个智能指针,两个智能指针现在共享同一资源,引用计数增加到 2。
这个实现确保在多线程环境中正确管理资源的生命周期,通过使用互斥锁来保护引用计数和资源的访问,避免了竞态条件和资源泄漏。