[英]C++ thread still `joinable()` after it finishes execution?
I have the following function: 我有以下功能:
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();
}
And I am using it the following way: 我使用它的方式如下:
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;
}
This is the output: 这是输出:
thread #21300 says hi
线程#21300说嗨
thread #21300 says hi
线程#21300说嗨
thread #21300 says hi
线程#21300说嗨
thread #21300 says hi
线程#21300说嗨
thread #21300 says hi
线程#21300说嗨
Finished executing thread #21300
完成执行线程#21300
thread #2136 says hi
线程#2136说嗨
thread #2136 says hi
线程#2136说嗨
thread #2136 says hi
线程#2136说嗨
thread #2136 says hi
线程#2136说嗨
thread #2136 says hi
线程#2136说嗨
Finished executing thread #2136
完成执行线程#2136
thread t2 is joinable: true
线程t2是可连接的:true
And then it crashes when the try block goes out of scope because abort()
was called on t2
. 然后当try块超出范围时崩溃,因为在
t2
调用了abort()
。
My question is, why is t2
still joinable()
even when its threadProc
was over? 我的问题是,为什么
t2
仍然可以joinable()
即使它的threadProc
结束了? Why did it not finish processing? 为什么没有完成处理?
Moreover, I am using WaitForSingleObject
to ensure that I wait until t2
finishes processing. 而且,我使用
WaitForSingleObject
来确保我等到t2
完成处理。 I also added the 5 seconds wait to make sure it takes its time to finish its processing. 我还添加了5秒等待,以确保它花费时间来完成其处理。 Yet something is still not done.
然而,有些事情仍未完成。
I know I can use t2.join()
or t2.detach()
but why do I have to? 我知道我可以使用
t2.join()
或t2.detach()
但我为什么要这样做? t2
has already finished processing (I think). t2
已经完成处理(我想)。
EDIT : I have tried the following code: 编辑 :我尝试了以下代码:
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;
}
And still the thread is joinable. 而且线程仍然可以连接。 I looked up the
joinable
reference and they say: 我查看了
joinable
参考文献,他们说:
A thread that has finished executing code, but has not yet been joined is still considered an active thread of execution and is therefore joinable.
已完成执行代码但尚未加入的线程仍被视为活动执行线程,因此可以连接。
So this isn't related to WaitForSingleObject
anymore. 所以这与
WaitForSingleObject
无关。 The question is why a thread is still considered joinable()
after it finished execution? 问题是为什么线程在完成执行后仍被认为是
joinable()
?
I have seen this question which confused me even more as it states that when the thread finished execution it was not joinable()
even before calling join()
or detach()
. 我已经看到这个问题让我更加困惑,因为它表明当线程完成执行时,即使在调用
join()
或detach()
之前它也不是joinable()
detach()
。
The question is why a thread is still considered joinable() after it finished execution?
问题是为什么线程在完成执行后仍被认为是joinable()?
Because you might want to write code that join()s it. 因为你可能想编写join()的代码。 If
t.joinable()
automatically became false upon termination, then there would be no safe way to call t.join()
. 如果
t.joinable()
在终止时自动变为false,那么就没有安全的方法来调用t.join()
。 You could write this: 你可以这样写:
if (t.joinable()) {
t.join();
}
But that still could throw an exception if the thread terminated after t.joinable()
had returned true
, but before the caller was able to complete the t.join()
call. 但是,如果线程在
t.joinable()
返回true
之后终止,但在调用者能够完成t.join()
调用之前终止,则仍会抛出异常。
Having the thread remain joinable until it actually is join()ed is simpler behavior to describe, and it's easier to write code that uses it correctly. 让线程保持可连接直到它实际上是join()ed是更简单的行为来描述,并且编写正确使用它的代码更容易。
joinable
doesn't mean still_running
, joinable simply means the thread object is not "empty" (as result of default construction or move) and is associated with a real OS-thread of execution. joinable
并不意味着still_running
,可连接只是意味着线程对象是不是“空”(如缺省结构或移动的结果),并与执行的真实OS线程相关联。
if the thread is empty, that means there is nothing to join, hence, the thread is not "joinable". 如果线程为空,则意味着没有任何东西可以连接,因此,线程不是“可连接的”。
if the thread is not empty, you can make the current thread wait for it, hence it is "joinable". 如果线程不为空,则可以使当前线程等待它,因此它是“可连接的”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.