reference counted class and multithreading

依然范特西╮ 提交于 2019-12-02 00:37:06

Your analysis isn't right; The code you posted is using interlockedDecrement correctly.

This is a safe use

 if(InterlockedDecrement(&mRefCount)==0)
           cleanup();

.. but this would indeed have the problem you described

 InterlockedDecrement(&mRefCount);

 if (mRefCount==0)
           cleanup();

However, the use of delete this is much more likely to be the cause of the problem. It's very unlikely you're passing the 'absolutely positively 100% sure' tests described here: http://www.parashift.com/c++-faq-lite/delete-this.html

In particular, the following simple code would cause chaos.

{
  RBuffer x;  // count is what... ? zero
  x.incRef(); // make count one
  x.decRef(); // make count zero, and deletes itself 
}  // now x goes out of scope, so destructor is called a second time = chaos! 

A normal "reference counting" idiom involves a 'shared object' (with the count), and simple 'reference objects' (not C++ references, although the semantics would be similar) which refer to the shared object. The constructors and destructors of the 'reference objects' are responsible for calling the incref/decref methods on the shared object. So the shared object is automatically counting the number of active 'reference objects'.

It is not 100% clear what is going on, but it looks like ThreadA deletes the RBuffer object, and then subsequently ThreadB dereferences it.

What you really need is mutual exclusion around decrement and the delete operation, furthermore you need to set some kind of flag to prevent dereference after delete. Usually setting pointers to NULL works and then checking for NULL before any dereference.

So your decRef might look something like this:

 void decRef() {
     lock(_mutex);
     if(InterlockedDecrement(&mRefCount)==0) {
               PointerToRBuffer = NULL;
               delete (Rbuffer *)this;
           }
    }

You might be better off using a shared_ptr.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!