[英]C++ thread still `joinable()` after it finishes execution?
我有以下功能:
void threadProc(){
for (int i = 0; i < 5; ++i) {
std::cout << "\n thread #" << std::this_thread::get_id() << " says hi";
}
std::cout << "\n Finished executing thread #" << std::this_thread::get_id();
}
我使用它的方式如下:
int main(){
try {
std::thread t1(threadProc);
t1.join();
std::thread t2(threadProc);
HANDLE handle = t2.native_handle();
WaitForSingleObject(handle, INFINITE);
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
std::cout << "\n thread t2 is joinable: " << std::boolalpha << t2.joinable() << "\n\n";
}
catch (std::exception& ex){
std::cout << "\n\n " << ex.what() << "\n\n";
}
return 0;
}
這是輸出:
線程#21300說嗨
線程#21300說嗨
線程#21300說嗨
線程#21300說嗨
線程#21300說嗨
完成執行線程#21300
線程#2136說嗨
線程#2136說嗨
線程#2136說嗨
線程#2136說嗨
線程#2136說嗨
完成執行線程#2136
線程t2是可連接的:true
然后當try塊超出范圍時崩潰,因為在t2
調用了abort()
。
我的問題是,為什么t2
仍然可以joinable()
即使它的threadProc
結束了? 為什么沒有完成處理?
而且,我使用WaitForSingleObject
來確保我等到t2
完成處理。 我還添加了5秒等待,以確保它花費時間來完成其處理。 然而,有些事情仍未完成。
我知道我可以使用t2.join()
或t2.detach()
但我為什么要這樣做? t2
已經完成處理(我想)。
編輯 :我嘗試了以下代碼:
int main() {
try {
std::thread t1([]() {std::cout << "\n\n Hi from thread #" << std::this_thread::get_id(); });
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
catch (std::exception& ex) {
std::cout << "\n\n " << ex.what() << "\n\n";
}
return 0;
}
而且線程仍然可以連接。 我查看了joinable
參考文獻,他們說:
已完成執行代碼但尚未加入的線程仍被視為活動執行線程,因此可以連接。
所以這與WaitForSingleObject
無關。 問題是為什么線程在完成執行后仍被認為是joinable()
?
我已經看到這個問題讓我更加困惑,因為它表明當線程完成執行時,即使在調用join()
或detach()
之前它也不是joinable()
detach()
。
問題是為什么線程在完成執行后仍被認為是joinable()?
因為你可能想編寫join()的代碼。 如果t.joinable()
在終止時自動變為false,那么就沒有安全的方法來調用t.join()
。 你可以這樣寫:
if (t.joinable()) {
t.join();
}
但是,如果線程在t.joinable()
返回true
之后終止,但在調用者能夠完成t.join()
調用之前終止,則仍會拋出異常。
讓線程保持可連接直到它實際上是join()ed是更簡單的行為來描述,並且編寫正確使用它的代碼更容易。
joinable
並不意味着still_running
,可連接只是意味着線程對象是不是“空”(如缺省結構或移動的結果),並與執行的真實OS線程相關聯。
如果線程為空,則意味着沒有任何東西可以連接,因此,線程不是“可連接的”。
如果線程不為空,則可以使當前線程等待它,因此它是“可連接的”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.