简体   繁体   English

C ++线程在完成执行后仍然是`joinable()`吗?

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM