为什么。当所有其他线程都在主线程之前完成时,连接仍然是必需的? 学习C++多线程。 在我的示例中,线程helper1和helper2在main线程完成之前已经完成了执行。然而,程序崩溃了。我特别拿出了.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"; } void foo() { //模拟昂贵的操作 std::this_thread::sleep_for(std::chrono::seconds(5)); std::cout
因为为什么。当所有其他线程都在主线程之前完成时,连接仍然是必需的? 学习C++多线程。 在我的示例中,线程helper1和helper2在main线程完成之前已经完成了执行。然而,程序崩溃了。我特别拿出了.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"; } void foo() { //模拟昂贵的操作 std::this_thread::sleep_for(std::chrono::seconds(5)); std::cout,c++,multithreading,C++,Multithreading,因为std:~thread调用terminate如果关联的线程仍然可以连接: 如果joinable(),则调用std::terminate()。否则,将无效[ 注意:隐式分离或在其析构函数中加入joinable()线程可能导致难以调试正确性(分离)或性能(连接)只有在引发异常时才会遇到错误。因此,程序员必须确保当线程仍然可连接时,不会执行析构函数。-结束说明] 您需要调用.detach()或.join()。除此之外,由于您无法确定操作系统如何调度线程,因此最终可能会以任何方式中断线程,因此最好使
std:~thread
调用terminate
如果关联的线程仍然可以连接:
如果joinable()
,则调用std::terminate()
。否则,将无效[
注意:隐式分离或在其析构函数中加入joinable()
线程可能导致难以调试正确性(分离)或性能(连接)只有在引发异常时才会遇到错误。因此,程序员必须确保当线程仍然可连接时,不会执行析构函数。-结束说明]
您需要调用.detach()
或.join()
。除此之外,由于您无法确定操作系统如何调度线程,因此最终可能会以任何方式中断线程,因此最好使用.join()
从头开始。基于,在调用析构函数时必须连接或分离基础线程。析构函数在退出main
时调用,并且可能假定已调用join
或detach
只要以下两行在构造helper1
和helper2
之后的某处,代码也不应该崩溃
helper1.detach()
helper2.detach()
CPU可以调度三个线程(
main
/thread1
/thread2
)以任何顺序。可能会发生您的main
没有时间运行,线程退出。因此,您需要在main
中保留join
,以处理此情况。线程调度是不可预测的,除非您使用的是RTOS,我认为您的问题没有意义,因为它是基于错误的假设。知道线程已完成的唯一方法是当线程的join()
返回时。在join()
返回之前,不是“线程已完成”。线程执行中的某些语句已完成可能是真的(例如,打印一条消息,或者更好地说,写入一个原子变量),但是线程函数本身的完成情况除了通过连接之外,无法以任何方式进行测量
因此,在您加入之前,所有线程都不会“完成”。是什么让您如此确信这两个线程[编辑:始终]在主线程之前完成?@dialer,我猜他只是在查看这两个线程的输出。“何时”如果不加入,则不是一个有意义的词。加入建立了时间顺序。我想补充一个问题:“如果主线程结束,并且在操作系统级别仍有运行的线程,会发生什么?”那么如果std::thread::~thread()不调用“terminate”呢?@DarioOO:您只需在线程上调用detach
,就可以实现这一点。这样就没有终止。
helper1.detach()
helper2.detach()