2017-02-16 112 views
0

在線程的while循環內調用joinable()函數以測試線程上是否存在加入請求或是否存在我目前不考慮的任何副作用是否合法?測試連接是否已被調用

+1

「測試線程上是否有加入請求」 - 這不是joinable()告訴你的。 –

+2

標準中沒有辦法檢查線程是否調用了'join'。如果你想終止線程,你可以使用'condition_variable'或'atomic '。 – NathanOliver

+0

謝謝。使用condition_variable和原子工作正常。 – Gustavo

回答

1

在線程的while循環中調用joinable()函數來測試線程上是否存在加入請求或是否存在我目前不考慮的副作用是否合法?

這可能會導致數據競爭(因此未定義行爲),除非你使用某種手動同步的。

std::thread::join()是非const成員函數,因此它的任何呼叫,其與任何其它的呼叫可能併發到相同的對象將衝突的成員函數,並造成數據的比賽。

因此,如果一個線程調用std::thread::join()並且另一個線程在同一個對象上同時調用std::thread::joinable(),那麼您將遇到數據競爭和未定義的行爲。

你可以通過使用一個互斥來序列化調用來解決這個問題,以便在任何時候只有一個對象訪問線程,但是我會考慮你的設計是否有意義。提示:它沒有。撥打joinable()會告訴您線程是否已加入,如果已撥打join(),則不會。線程在運行時不能加入(對join()的調用將阻止並等待它完成)。所以正在運行的線程永遠不會看到joinable() == false對於管理它的std::thread對象,因爲如果它能夠調用joinable()那麼它仍然在運行,所以它可以連接!

所以:除非你非常小心

  1. 試圖做到這一點的風險不確定的行爲。

  2. 無論如何這是沒有道理的。

而是使用類似一個std::atomic<bool>(或boolstd::mutex)記錄該線程是否已經請求停止運行,並從正在運行的線程檢查。