多线程中的单例使用

时间:2013-07-30 08:38:00

标签: c++ synchronization

我正在阅读一本关于锁定和设计的应用C ++的书。

void addRef() { ref++; }
void subRef() { if(--ref == 0) delete this; }
  

尽管像ref ++这样的语句看起来微不足道,但并不能保证   它是原子的。但在你去重写这个代码之前添加   锁定,你需要知道你的应用程序将如何使用它。在这   特别的例子,如果在subRef之后调用addRef,则会创建一个bug。   问题不在于缺少锁,而是设计不佳。如果是一个对象   必须坚持超出线程的范围,它应该被创建和拥有   通过不会超出范围的不同线程。

我对上述文字的质询是

  1. 作者的设计意味着什么以及如何避免这种情况?如果一个对象必须超出一个线程的范围,它应该由一个不会超出范围的不同线程创建和拥有。 #34; ?请求举例说明。

3 个答案:

答案 0 :(得分:1)

void thread1work(RefCntObj* refcntObj) 
{
  refcntObj.addRef();
  // any work
  refcntObj.subRef();
}

int main(void) {
  RefCntObj* refcntObj= new RefCntObj(); // I assume the constructor calls addRef()
  std::thread t(thread1work, std::ref(f));
  refcntObj->subRef(); // may be called after thread1Work or before it
}

无法保证在主thread1work之前调用refcntObj->subRef();。在这种情况下,对象将被删除,指针无效。

答案 1 :(得分:0)

由于代码设计不佳,作者意味着类和方法的构造很差;您放置什么以及如何使您的代码可访问的位置。

  

“如果一个对象必须超出一个线程的范围,它应该由一个不会超出范围的不同线程创建和拥有。”

简单地说,上面的意思是如果你在A(线程)中有B但是你也需要在C中使用B,那么你必须从线程(A)中删除B并使其独立于它,所以你可以在A和C中使用它。

答案 2 :(得分:0)

谁知道?你必须问作者。这看起来像 古典参考指向我:为了安全,你必须 要么使用互斥锁来保护对ref的所有访问,要么使用。{ ref某种原子变量。 (C ++ 11有一个完整的范围 您可以使用std::atomic<int>上的函数。)

关于引用的文字:如果,你可以做任何不安全的事情 你没有正确使用它。如果两个线程访问相同的 例如,ref应该已经至少为2,所以if 一个线程删除引用,该对象仍将继续 存在。不需要任何额外的线程 事情变得复杂。