转载

Lock Free中的Hazard Pointer(中)

看过上篇的朋友,可能会认为:这不就是 Smart Pointer 么?于是可能写出这样的代码:

#include<iostream> #include<thread> using namespace std; class SmartPointer { public:   SmartPointer(int *p)   {     pointee_ = p;     ref_counts_ = 0;   }   int *pointee_;   int ref_counts_; }; SmartPointer sp(new int(1)); void Reader() {   ++sp.ref_counts_;   cout<<*(sp.pointee_)<<endl;   --sp.ref_counts_; } void Writer() {   if (sp.ref_counts_ == 0)     delete sp.pointee_; } int main() {   std::thread t1(Reader);   std::thread t2(Reader);   std::thread t3(Reader);   std::thread t4(Writer);   t1.join();   t2.join();   t3.join();   t4.join();   return 0; } 

然而事实上,这样做是错的。其中的 race condition 请读者自行分析。

那么, Hazard Pointer ( HP )和 Smart Pointer ( SP )有什么区别呢?它们的共同点就是管理对应对象的生命周期,然而这两者有本质的区别, HP 是线程安全的,而 SP 不是。

HP 中,每个读线程维护着自己的 HP list ,这个 list ,只由该线程写。因此,它是线程安全的。该 list 会(可以)被其他线程读。

每个写线程维护自己的 retire list ,该 retire list 只由该写线程进行读写。由于写线程可以读其他所有读线程的 HP list ,这样,差集(在自己的 retire list ,但是不在所有读线程的 HP list 里的指针),就是可以安全释放的指针。

SP ,则被多个线程读写, 18、19 两行也无法做成原子操作,因此, SPHP 有本质的区别,使用 SP 的程序往往需要搭配使用锁等设施来保证线程安全。

正文到此结束
Loading...