[英]std::thread thread spun off in object, when does it terminate?
如果我在Bar
的構造函數中關閉std::thread
,它什么時候停止運行? 當Bar
實例被破壞時,它是否可以保證停止?
class Bar {
public:
Bar() : thread(&Bar:foo, this) {
}
...
void foo() {
while (true) {//do stuff//}
}
private:
std::thread thread;
};
編輯:如何正確終止析構函數中的std::thread
?
如果我在Bar的構造函數中關閉std :: thread,它什么時候停止運行?
只要它執行你提供的調用,或者程序終止,線程就會運行。
當Bar實例被破壞時,它是否可以保證停止?
不。為了保證這一點,在Bar
析構函數中調用std::thread::join
。
實際上,如果你沒有在Bar::~Bar
之前調用thread::join
或thread::detach
,那么你的應用程序將通過自動調用std::terminate
來std::terminate
。 所以你必須要么join
(優先)或detach
(少推薦)。
你還想在對象析構函數上調用therad::join
,因為生成的線程依賴於對象是活的 ,如果在你的線程處理該對象時對象被破壞 - 你正在使用被破壞的對象而你將有未定義的行為在你的代碼中。
C ++線程工具不包含用於終止線程的內置機制。 相反,你必須自己決定:a)一個機制來通知線程它應該終止,b)你不關心線程在進程終止時在操作中被中止並且操作系統只是停止運行它的線程任何更多。
std::thread
對象不是線程本身,而是包含線程的描述符/句柄的不透明對象,因此理論上它可以在不影響線程的情況下被銷毀,並且存在支持和反對線程自動終止的參數。 相反,作為妥協,它是這樣做的,以便在線程保持運行和附加時銷毀std::thread
對象將導致應用程序終止。
結果,在它的析構函數中有一些代碼如下:
~thread() {
if (this->joinable())
std::terminate(...);
}
這是一個使用簡單原子變量並在線程中檢查它的示例。 對於更復雜的情況,您可能需要考慮condition_variable
或其他更復雜的信令機制。
#include <thread>
#include <atomic>
#include <chrono>
#include <iostream>
class S {
std::atomic<bool> running_;
std::thread thread_;
public:
S() : running_(true), thread_([this] () { work(); }) {}
void cancel() { running_ = false; }
~S() {
if ( running_ )
cancel();
if ( thread_.joinable() )
thread_.join();
}
private:
void work() {
while ( running_ ) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "tick ...\n";
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "... tock\n";
}
std::cout << "!running\n";
}
};
int main()
{
std::cout << "main()\n";
{
S s;
std::this_thread::sleep_for(std::chrono::milliseconds(2750));
std::cout << "end of main, should see a tock and then end\n";
}
std::cout << "finished\n";
}
現場演示: http : //coliru.stacked-crooked.com/a/3b179f0f9f8bc2e1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.