[英]How to end a thread properly?
我的主程序創建了一個線程。 該線程初始化一些數據,然后進入“while”循環並運行,直到主程序將控制變量設置為“false”。 然后它調用 join() 女巫無休止地阻塞整個代碼。
bool m_ThreadMayRun;
void main(){
thread mythread = thread(&ThreadFunction);
//do stuff
m_ThreadMayRun = false;
mythread.join(); // this blocks endlessly even when I ask 'joinable' before
}
void ThreadFunction{
initdata();
m_ThreadMayRun=true;
while(m_ThreadMayRun){
//do stuff that can be / has to be done for ever
}
deinitdata();
}
感謝幫助
您有兩個線程寫入m_ThreadMayRun
的競爭條件。 考慮如果首先主線程執行m_ThreadMayRun = false;
會發生什么然后你創建的線程執行m_ThreadMayRun = true;
,那么你有一個無限循環。 然而,嚴格來說,這條推理線是無關緊要的,因為當你有競爭條件時,你的代碼會有未定義的行為。
我在這里錯過了什么嗎?
您需要通過使其成為std::atomic<bool>
或使用std::mutex
來同步對m_ThreadMayRun
的訪問,並確保在m_ThreadMayRun = false
= true 之后執行m_ThreadMayRun = true;
.
PS對於這種情況,最好使用std::condition_variable
。
問題是訪問bool m_ThreadMayRun;
是不同步的,並且根據 C++ 規則,每個線程可以假設它在線程之間沒有變化。 所以你最終會遇到一場比賽(一種未定義的行為)。
為了明確意圖,使其成為atomic
的。
std::atomic<bool> m_ThreadMayRun;
這樣, m_ThreadMayRun
的每個加載/存儲都變成了 memory 柵欄,由於原子加載/存儲的獲取/釋放語義,它不僅同步了自己的值,而且還使線程完成的其他工作可見。
盡管線程中的m_ThreadMayRun = true
和設置m_ThreadMayRun = false
之間仍然可能存在小競爭。 任何一個都可以先執行,有時會導致不希望的結果。 為避免這種情況,請在啟動線程之前將其初始化為true
。
std::atomic<bool> m_ThreadMayRun;
void main(){
m_ThreadMayRun = true;
thread mythread(&ThreadFunction);
//do stuff
m_ThreadMayRun = false;
mythread.join(); // this blocks endlessly even when I ask 'joinable' before
}
void ThreadFunction{
initdata();
while(m_ThreadMayRun){
//do stuff that can be / has to be done for ever
}
deinitdata();
}
有關 memory 柵欄和獲取/釋放語義的更多詳細信息,請參閱以下優秀資源:《 C++ Concurrency in Action 》一書和 Herb Sutter 的atomic<>
武器談話。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.