当所有其他线程在主线程之前完成时,为什么.join仍然是必需的?

new*_*int 7 c++ multithreading

学习C++多线程.
在我的例子中,线程helper1helper2main线程完成之前完成执行.但是,程序崩溃了.我特意,拿出.join()语句,看看程序将如何表现,期待没有错误,因为在其他两个线程完成后main()调用std::terminate.

void foo()
{
    // simulate expensive operation
    std::this_thread::sleep_for(std::chrono::seconds(5));
    std::cout << "t1\n";
}

void bar()
{
    // simulate expensive operation
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "t2\n";
}

int main()
{

    std::cout << "starting first helper...\n";
    std::thread helper1(foo);

    std::cout << "starting second helper...\n";
    std::thread helper2(bar);


    std::this_thread::sleep_for(std::chrono::seconds(10));

    std::cout << "waiting for helpers to finish..." << std::endl;
    //helper1.join();
    //helper2.join();

    std::cout << "done!\n";
}
Run Code Online (Sandbox Code Playgroud)

Ker*_* SB 6

我会说你的问题没有意义,因为它是基于错误的假设.要知道,唯一的方法一个线程完成是线程的时候join()回报.在join()返回之前,不是"线程已完成"的情况.可能确实线程执行中的某些语句已经完成(例如,打印消息,或者更好,写入原子变量),但是线程函数本身的完成除了通过加入之外不能以任何方式测量.

所以在你加入之前,所有的线程都没有 "完成".


Zet*_*eta 5

因为如果关联的线程仍可联接,则会std::~thread调用terminate

30.3.1.3线程析构函数[thread.thread.destr]

~thread();
Run Code Online (Sandbox Code Playgroud)

如果joinable(),请致电std::terminate()。否则,没有任何效果。[注意:joinable()仅在引发异常时,隐式地在其析构函数中分离或联接线程都可能导致调试(在分离时)或性能(在联接时)错误的调试困难。因此,程序员必须确保在线程仍可连接的同时不执行析构函数。—尾注]

需要致电.detach().join()。除此之外,由于无法确定操作系统如何调度线程,因此最终可能会以任何方式中断线程,因此.join()从一开始就更好地使用它。