2011-06-02 146 views
9

我有一個工作人員std::thread,我希望它的主循環檢查是否有其他線程告訴它停止循環並退出。
什麼是一個很好的跨平臺方式來做到這一點? boost是否爲它提供了一些事件對象?
正在使用只是一個bool認爲線程安全?優雅地停止一個std ::線程?

+0

你所說的「使用」這裏是什麼意思?一般來說,答案總是「否」:除'atomic'之外的任何類型本質上都是線程安全的。 – 2011-06-02 12:13:36

+0

鎖('std :: mutex')不適合這個。不幸的是,C++ 0x並沒有繼承'boost :: thread :: interrupt',這是非常遺憾的。看[這些](http://stackoverflow.com/questions/2845704/how-to-interrupt-a-waiting-c0x-thread)[two](http://stackoverflow.com/questions/2790346/c0x-thread - 中斷)問題。 – 2011-06-02 12:27:19

+1

@Tomalak:請解釋使用互斥鎖的問題。這似乎是最簡單和最明顯的解決方案。 – 2011-06-02 12:31:35

回答

7

..以及它依賴。線程在做什麼?它阻塞任何東西,I/O,sleep還是其他一些API?

如果它只是CPU套住所有不要緊究竟何時停止停止並退出,然後只使用一個布爾時間。在這種情況下,鎖定'stopAndExit'布爾值沒有意義。

如果工作線程在一個循環中沒有將其讀爲真,那麼可能它應該,因爲缺乏原子性,它會在下一次得到它。爲什麼在不需要時執行鎖定/ API調用?從用戶獲取/釋放同步對象的內核級調用將花費時間與簡單的「if(stop)exit」相比,浪費了每個可用於計算的循環的時間,或者在CPU中執行的任何操作,綁定線程。

它是跨平臺的

問候, 馬丁

+3

+1爲了讓人們認爲如果昂貴的同步方法真的需要所有的 時間。 – 2011-06-02 13:30:07

+9

我不明白這可以如何保證工作。如果沒有內存屏障或易失性讀取語義,對於編譯器是否有效地優化了寄存器中變量的值?在這種情況下,它永遠不會看到更新。我可以告訴你,這種類型的問題**絕對存在於.NET中(如果一個多線程程序經常檢查一個布爾條件,它可能會進入一個無限循環,即使它現在實際上是'真',因爲它是從另一個線程更新的)。 – bobbymcr 2011-12-25 20:28:48

+0

@bobbymcr - 嘗試使用除了非常微不足道的線程之外的任何東西,專門用於顯示此問題。這不會發生在英特爾上,我不會在Spark上發生,它不會發生在我曾經用過的任何事情上。這種情況不會發生,因爲如果你的呼吸聲太大,寄存器會在驅動程序中斷,函數調用中溢出到L1緩存中。 – 2013-04-07 22:33:22

2

你可能有一個std :: mutex在主線程和你的工作線程之間共享。

您的工作線程可以在開始任何工作並間歇性釋放之前獲取std :: mutex :: try_lock。當主線程想要關閉工作線程時,可以鎖定該互斥鎖。你的工作線程可以使用try_lock檢測到這個並退出

+4

扭轉它可能的性能好處?主線程持有鎖,工作線程嘗試(非阻塞)在循環開始時獲取它,成功時退出。每次都釋放循環,主線程不必坐在等待循環完成,如果它有其他的東西要做。 – 2011-06-02 12:29:08

0

std :: mutex,它的親屬是核心機制。 std :: lock_guard和unique_lock在此基礎上構建,而std :: condition_variable則適用於此目的。

0

正如你所說的boost,你可以使用boost :: thread。

在你的情況下,啓動一個線程後,你可以使用interrupt()方法來中斷它。接收線程可以用boost :: this_thread :: interruption_point()方法檢查中斷請求。如果有中斷請求,這將導致線程退出,否則它將忽略它。

您可以查看這裏的文檔: Boost Thread Documentation

+0

請注意,std :: thread基於Boost線程設計[link] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2184.html - 所以可以說std會更便攜(儘管目前在支持的平臺上可能沒有什麼區別)。 – holtavolt 2011-06-02 13:03:01

+2

std :: thread從中刪除了'interrupt'。 :-( – 2011-06-02 13:52:23

+0

@Howard你是否知道它爲什麼被刪除,或者更可怕:爲什麼C++ 14/17仍然沒有它? – rubenvb 2017-06-03 23:10:42