[英]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.