Mos*_*aev 31 c++ multithreading
我不明白为什么当std::thread
销毁销毁时它必须处于join()或detach()状态。
联接等待线程完成,而分离则没有。似乎有些中间状态我不了解。因为我的理解是join和detach是互补的:如果不调用join(),则默认为detach()。
这样说,假设您正在编写一个创建线程的程序,并且仅在此线程的生命周期后期才调用join(),所以直到您调用join为止,该线程基本上像分离的线程一样在运行,没有?
从逻辑上讲,detach()应该是线程的默认行为,因为这是线程的定义,它们与其他线程无关地并行执行。
那么,当线程对象被破坏时,为什么要调用Terminate()?为什么标准不能简单地将线程视为已分离?
我不了解在销毁线程之前未调用join()或detached()时终止程序的原因。这样做的目的是什么?
更新:
我最近遇到了这个。安东尼·威廉姆斯(Anthony Williams)在他的《并发中的行动》一书中指出:“ C ++ 17的建议之一是为join_thread类提供类似于std :: thread的要求,只是它会像scoped_thread一样自动加入析构函数中。这在委员会中没有达成共识,因此未被标准接受(尽管对于C ++ 20来说,它仍然可以按std :: jthread的标准进行...)”
fif*_*ifo 37
从技术上讲,答案是“因为规范如此规定”,但这是一个晦涩的答案。我们无法理解设计师的想法,但是以下一些问题可能是造成这些问题的原因:
使用POSIX pthread,子线程必须在退出后再加入,否则子线程将继续占用系统资源(例如内核中的进程表条目)。这是通过完成的pthread_join()
。如果进程对子线程持有一个HANDLE,则Windows有一个类似的问题。尽管Windows不需要完全连接,但是该进程仍必须调用CloseHandle()
以在线程上释放其refcount。
由于std::thread
是跨平台的抽象,因此受到需要连接的POSIX要求的约束。
从理论上讲,std::thread
析构函数可以调用pthread_join()
而不是引发异常,但这(主观上)可能增加死锁的风险。而正确编写的程序将知道何时在安全时间插入连接。
也可以看看:
Chr*_*odd 15
您会感到困惑,因为您正在将std::thread
对象与其所引用的执行线程相混淆。甲std::thread
对象是一个C ++对象(一堆存储器字节)充当到执行的线程的参考。当您调用时std::thread::detach
,发生的事情是该std::thread
对象与执行线程“分离”了-它不再引用(任何)执行线程,并且执行线程继续独立运行。但是std::thread
对象仍然存在,直到被销毁为止。
执行线程完成后,它将其退出信息存储到std::thread
引用它的对象中,如果有一个(如果是分离的,则没有一个,因此退出信息将被丢弃。)它没有对std::thread
对象的其他影响-特别是该std::thread
对象不会被销毁,并且会继续存在,直到有人销毁它为止。