多线程中的单例使用 我正在读一本关于C++的设计和锁的书。 void addRef() { ref++; } void subRef() { if(--ref == 0) delete this; }

多线程中的单例使用 我正在读一本关于C++的设计和锁的书。 void addRef() { ref++; } void subRef() { if(--ref == 0) delete this; },c++,synchronization,C++,Synchronization,尽管像ref++这样的语句看起来微不足道,但不能保证 它是原子的。但是在你去重写这段代码之前 锁定时,您需要知道应用程序将如何使用它。在这个 例如,如果在subRef之后调用addRef,则会创建一个bug。 问题不在于缺少锁,而是设计拙劣。如果一个物体 必须在线程的作用域之外保持,它应该被创建和拥有 由另一个不会超出范围的线程执行 我对上述案文的问题是: 作者所说的糟糕的设计是什么意思,以及如何通过“如果一个对象必须在线程范围之外持久存在,它应该由另一个不会超出范围的线程创建和拥有”来避免这种

尽管像ref++这样的语句看起来微不足道,但不能保证 它是原子的。但是在你去重写这段代码之前 锁定时,您需要知道应用程序将如何使用它。在这个 例如,如果在subRef之后调用addRef,则会创建一个bug。 问题不在于缺少锁,而是设计拙劣。如果一个物体 必须在线程的作用域之外保持,它应该被创建和拥有 由另一个不会超出范围的线程执行

我对上述案文的问题是:

  • 作者所说的糟糕的设计是什么意思,以及如何通过“如果一个对象必须在线程范围之外持久存在,它应该由另一个不会超出范围的线程创建和拥有”来避免这种情况?请给出一个例子

  • 通过糟糕的代码设计,作者意味着糟糕的类和方法构造;放置位置以及该位置如何使代码可访问

    如果一个对象必须在线程的作用域之外持久存在,它应该由一个不会超出作用域的不同线程创建和拥有

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

    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
    }
    

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

    谁知道呢?你得问问作者。这看起来像 经典参考对我来说:为了安全,你必须 向用户提供一个互斥锁以保护对
    ref
    的所有访问,或使
    ref
    某种原子变量。(C++11有一整套 可以使用的
    std::atomic
    上的函数。)

    关于引用的文本:如果 你用得不对。如果两个线程正在访问同一个 实例,则
    ref
    应该至少为2,因此如果 一个线程删除引用,对象仍将继续 存在。不需要添加任何额外的线程
    使事情复杂化。

    std::atomic
    也可以。但是
    删除这个
    无论如何都是可怕的-被计数的对象中的引用计数器有什么用?为什么你在问题标题中提到singleton,而在实际问题中与它无关?