2017-09-04 66 views
15

我一直在閱讀關於多線程,C++,適當的同步和鎖定以防止競爭條件的不同事情。還有一個問題沒有回答我,但是: 有沒有,如果我創建一個線程對象需要一個互斥體,但事後在線程B專門使用它?在線程A中創建對象,在線程B中使用。需要Mutex?

換句話說,我知道我不需要互斥體來防止競爭條件 - 我需要互斥體作爲內存屏障(或其他潛在問題)嗎?

一個非常簡單的例子,以可視化我的意思

struct Object { 
    void do_stuff(); 
}; 

Object o; 
std::thread worker_thread([&o](){ 
    while (alive) 
     o.do_stuff(); 
}).join(); 
// `o` is never used outside worker_thread 

我會很高興,如果你也可以推薦我的文章/書籍,我可以閱讀更多有關這一主題和/或正確的關鍵字來搜索這些場景。

+3

如果只有一個線程使用對象,*您可以對*算的話,你應該沒有問題。 – Basya

回答

18

這很好,你不需要mutex

創建線程會設置內存屏障,因此通過傳遞給worker_thread的引用訪問o是安全的。

§30.3.2.2-6 - [thread.thread.constr]

構造函數的調用的完成與f的副本的調用開始同步。

雖然worker_thread運行時,顯然你不能在創建它的線程訪問o(如你所說)。

加入線程也會設置一個障礙,所以在worker_thread加入之後,您可以在主線程中再次訪問o

§30.3.2.5-4 - [thread.thread.destr]

通過*與此(1.10)對應的成功的加入()的返回同步表示的線程的完成。

對於進一步閱讀:

  • 安東尼·威廉姆斯在並行編程寫了一本好書(C++並行行動
  • 了Bjarne Stroustrup的書(C++編程語言,第4版)在併發編程方面有兩個很好的章節。
  • 傑夫Preshing有許多關於這些主題一個很好的博客;退房preshing.com
+1

完美,非常感謝。我實際上正在讀取C++併發性,但無法找到這些信息。但我想這是因爲我沒有在我的腦海 – user823255

+1

歡迎線程的創建和內存屏障之間的連接。它有時也具有挑戰性,找到共同點,因爲它們是不同的主題通常涵蓋不同的章節 – LWimsey