reference counted class and multithreading

前端 未结 2 680
梦如初夏
梦如初夏 2021-01-21 17:29

I \'m a novice in multithreading programing and i have still confusion with that.

Below is my reference counted class:

class Rbuffer
{
  private:
    cha         


        
相关标签:
2条回答
  • 2021-01-21 18:14

    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'.

    0 讨论(0)
  • 2021-01-21 18:14

    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.

    0 讨论(0)
提交回复
热议问题