我正在阅读一本关于锁定和设计的应用C ++的书。
void addRef() { ref++; }
void subRef() { if(--ref == 0) delete this; }
尽管像ref ++这样的语句看起来微不足道,但并不能保证 它是原子的。但在你去重写这个代码之前添加 锁定,你需要知道你的应用程序将如何使用它。在这 特别的例子,如果在subRef之后调用addRef,则会创建一个bug。 问题不在于缺少锁,而是设计不佳。如果是一个对象 必须坚持超出线程的范围,它应该被创建和拥有 通过不会超出范围的不同线程。
我对上述文字的质询是
答案 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
一个线程删除引用,该对象仍将继续
存在。不需要任何额外的线程
事情变得复杂。