C++多線程下的shared_ptr

來(lái)看一下boost文檔下給出的shared_ptr的多線程讀寫的例子

shared_ptr<int> p(new int(42));

//一個(gè)shared_ptr實(shí)體允許被多個(gè)線程讀取
// thread A
shared_ptr<int> p2(p); // reads p
// thread B
shared_ptr<int> p3(p); // OK, multiple reads are safe

//一個(gè)shared_ptr實(shí)體不允許被多個(gè)線程同時(shí)讀寫
// thread A
p = p3; // reads p3, writes p
// thread B
p3.reset(); // writes p3; undefined, simultaneous read/write

shared_ptr引用計(jì)數(shù)是原子的,它的析構(gòu)函數(shù)原子地將引用計(jì)數(shù)減去1,當(dāng)多個(gè)線程對(duì)同一對(duì)象析構(gòu)時(shí),也只會(huì)出現(xiàn)執(zhí)行順序的交錯(cuò),不會(huì)有內(nèi)存泄露。
那么同理shared_ptr的構(gòu)造函數(shù)、賦值、析構(gòu)都是線程安全的。

何時(shí)不安全呢?就是在我們通過shared_ptr.get()和*解引用獲得了指向該內(nèi)存的原始指針,那么后面都是對(duì)原始指針的操作,所以我們需要自己控制線程的安全。(如shared_ptr.rest 和 swap)

通俗來(lái)講,當(dāng)我們同時(shí)讀寫同一個(gè)對(duì)象的時(shí)候,無(wú)法確保編譯器是先操作引用計(jì)數(shù)還是先操作指針,在這個(gè)時(shí)候就需要加鎖,避免出現(xiàn)空懸指針

那么如何使多個(gè)線程可以對(duì)同一個(gè)shared_ptr實(shí)體進(jìn)行同時(shí)讀寫?

運(yùn)用weak_ptr這個(gè)助手檢測(cè)指針是否被釋放
沒使用前:

class tester 
{
public:
  tester() {}
  ~tester() {}
public:
  boost::shared_ptr<int> m_spData; // 可能其它類型。
};

tester gObject;

void fun(void)
{
  // !!!在這大量使用sp指針.
  boost::shared_ptr<int> tmp = gObject.m_spData;
}

int main()
{
  // 多線程。
  boost::thread t1(&fun);
  boost::thread t2(&fun);
  t1.join();
  t2.join();
  return 0;
}

改進(jìn)后:

class tester 
{
public:
  tester() {}
  ~tester() {}
  // 更多的函數(shù)定義…
};

void fun(boost::weak_ptr<tester> wp)
{
  boost::shared_ptr<tester> sp = wp.lock;
  if (sp)
  {
    // 在這里可以安全的使用sp指針.
  }
  else
  {
    std::cout << “指針已被釋放!” << std::endl;
  }
} 

int main()
{
  boost::shared_ptr<tester> sp1(new tester);
  boost.weak_ptr<tester> wp(sp1);
  // 開啟兩個(gè)線程,并將智能指針傳入使用。
  boost::thread t1(boost::bind(&fun, wp));
  boost::thread t2(boost::bind(&fun, wp));
  t1.join();
  t2.join();
  return 0;
}

使用weak_ptr.lock函數(shù)就可以得到一個(gè)shared_ptr的指針,如果該指針已經(jīng)被其它地方釋放,它則返回一個(gè)空的shared_ptr,也可以使用weak_ptr.expired()來(lái)判斷一個(gè)指針是否被釋放

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,676評(píng)論 1 51
  • 本文版權(quán)歸 liancheng 所有,如有轉(zhuǎn)載請(qǐng)按如下方式標(biāo)明原創(chuàng)作者及出處,以示尊重??!原創(chuàng)作者:lianche...
    周肅閱讀 7,865評(píng)論 2 6
  • 1. C++基礎(chǔ)知識(shí)點(diǎn) 1.1 有符號(hào)類型和無(wú)符號(hào)類型 當(dāng)我們賦給無(wú)符號(hào)類型一個(gè)超出它表示范圍的值時(shí),結(jié)果是初始值...
    Mr希靈閱讀 18,169評(píng)論 3 82
  • 原作者:Babu_Abdulsalam 本文翻譯自CodeProject,轉(zhuǎn)載請(qǐng)注明出處。 引入### Ooops...
    卡巴拉的樹閱讀 30,362評(píng)論 13 74
  • 因?yàn)楣纺?,我特別記起我們家養(yǎng)過的一條狗。 那是一條極普通的狗,普通到我想不起它有什么特別之處。只因?yàn)樗俏覀兗茵B(yǎng)過...
    Lin太陽(yáng)閱讀 400評(píng)論 2 2

友情鏈接更多精彩內(nèi)容