muduo 執行緒安全的物件生命期管理

2021-09-05 12:30:58 字數 1544 閱讀 4735

六、系統地避免各種指標錯誤

七、shared_ptr 技術與陷阱

八、小結

當乙個物件能被多個執行緒同時看到時,那麼物件的銷毀時機就會變得模糊不清,可能出現多種競態條件(race condition):

解決這些race condition是 c++ 多執行緒程式設計面臨的基本問題。本文試圖以shared_ptr一勞永逸地解決這些問題。

執行緒安全的定義】:

乙個執行緒安全的 class 應當滿足以下三個條件:

物件構造要做到執行緒安全,唯一的要求是在構造期間不要洩露 this 指標,即:

// 不要這麼做( don't do this.)

class

foo:

public observer

virtual

void

update()

;};// 物件構造的正確方法:

// 要這麼做(do this)

class

foo:

public observer};

foo* pfoo =

new foo;

observable* s =

getsubject()

;pfoo-

>

observe

(s);

// 二段式構造,或者直接寫 s->register_(pfoo);

mutex 只能保證函式乙個接乙個地執行,考慮下面的**,它試圖用互斥鎖來保護析構函式:(注意**中的 (1) 和 (2) 兩處標記。)

儘管執行緒 a 在銷毀物件之後把指標置為了 null,儘管執行緒 b 在呼叫 x 的成員函式之前檢查了指標 x 的值,但還是無法避免一種 race condition:

假如執行緒a通過p1將object物件銷毀了,這時候p2就變成了野指標或者叫空懸指標,這是一種典型的記憶體錯誤:

shared_ptr是引用計數型智慧型指標,當引用計數變為0時,物件被銷毀。weak_ptr(主要是解決shared_ptr迴圈引用的問題,將其中乙個shared_ptr換成weak_ptr即可)也是引用計數型智慧型指標,但是它不增加物件的引用次數,即弱引用。

雖然我們借 shared_ptr 來實現執行緒安全的物件釋放,但是 shared_ptr 本身不是100% 執行緒安全的。它的引用計數本身是安全且無鎖的,但物件的讀寫則不是,因為shared_ptr 有兩個資料成員,讀寫操作不能原子化。根據文件 11,shared_ptr 的執行緒安全級別和內建型別、標準庫容器、 std::string 一樣,即:

請注意,以上是 shared_ptr 物件本身的執行緒安全級別,不是它管理的物件的執行緒安全級別。

執行緒安全的物件生命期管理

1.當析構函式遇到多執行緒 在即將析構乙個物件時,別的執行緒是否正在執行該物件的成員函式?如何保證在執行成員函式期間,物件不在另乙個執行緒被析構?在呼叫某個成員函式之前,如何確保物件還活著?析構函式會不會執行到一半?1.1執行緒安全類 多個執行緒同時訪問,表現出正確的行為 無論作業系統如何排程這些執...

執行緒安全的物件生命期管理(三)

c 裡可能出現的記憶體問題大致有這麼幾個方面 1 緩衝區溢位 2 空懸指標 野指標 3 重複釋放 4 記憶體洩漏 5 不配對的new delete 6 記憶體碎片 正確使用智慧型指標能很容易地解決前面5個問題。1 緩衝區溢位 用vector string或自己編寫buffer class來管理緩衝區...

執行緒安全的物件生命期管理(七)

物件池 舉例 class stockfactory boost noncopyable 這段 中有乙個問題,stock物件永遠不會被銷毀,因為map裡存的是shared ptr,那就改為weak ptr class stockfactory boost noncopyable shared ptrs...