ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c-引用计数类和多线程

2019-10-11 12:10:08  阅读:253  来源: 互联网

标签:reference-counting c multithreading


我是多线程编程的新手,对此我仍然感到困惑.

以下是我的参考计数课程:

class Rbuffer
{
  private:
    char *m_pnData;
    volatile unsigned int mRefCount;

  public:
     Rbuffer(int nLength) : mRefCount(0)
    {
    m_pnData = new char[nLength]; 
    }
   ~Rbuffer(){
    delete[] m_pnData;
    }

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

  void incRef() {
        InterlockedIncrement(&mRefCount);
    } 

}; 

它是完全线程安全的吗?您能否排除这种情况:

ThreadA                                 ThreadB
PointerToRBuffer->incRef();//mRefCount 1
switch->  
                                        PointerToRBuffer->incRef();//mRefCount 2
                                          <-switch
PointerToRBuffer->decRef();           
InterlockedDecrement(&mRefCount)//mRefCount 1 
switch->                                
                                        PointerToRBuffer->decRef();//mRefCount 0!
                                        InterlockedDecrement(&mRefCount);
                                        if (0==0)
                                        delete (Rbuffer *)this; 
                                            <-switch
if (0==0) 
//deleting object, that doesn't exist 
delete (Rbuffer *)this;
//CRASH                               

崩溃的原因可能只是(InterlockedDecrement(& mRefCount))部分是原子的,但是如果(InterlockedDecrement(& mRefCount)== 0)不是吗?
我上面的例子错了吗?

在此先感谢您的意见和建议,以使我的课程完全线程安全.

解决方法:

您的分析不正确;您发布的代码正确使用了interlockedDecrement.

这是安全使用

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

..但这确实会有您描述的问题

 InterlockedDecrement(&mRefCount);

 if (mRefCount==0)
           cleanup();

但是,使用delete this更有可能是问题的原因.您极不可能通过此处描述的“绝对肯定100%肯定”测试:
http://www.parashift.com/c++-faq-lite/delete-this.html

特别是,以下简单代码会引起混乱.

{
  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! 

常规的“引用计数”惯用语涉及“共享对象”(带有计数)和引用共享对象的简单“引用对象”(不是C引用,尽管语义相似). “引用对象”的构造函数和析构函数负责在共享对象上调用incref / decref方法.因此,共享库会自动计算活动“参考对象”的数量.

标签:reference-counting,c,multithreading
来源: https://codeday.me/bug/20191011/1892281.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有