3 回答
TA贡献1785条经验 获得超4个赞
原始问题“ main()
退出时分离线程会发生什么”的答案是:
它继续运行(因为标准并没有说它已停止),并且这是定义良好的,只要它既不接触其他线程的(自动| thread_local)变量也不接触静态对象。
这似乎允许允许线程管理器作为静态对象(注意[basic.start.term] / 4中的注释,因为指针的@dyp)。
当静态对象的破坏完成时会出现问题,因为执行进入只有信号处理程序允许的代码可以执行的状态([basic.start.term] / 1,第一句)。在C ++标准库中,只有<atomic>
库([support.runtime] / 9,第二句)。特别是,通常 - 排除 condition_variable
(它的实现定义是否保存在信号处理程序中使用,因为它不是其中的一部分<atomic>
)。
除非你在这一点上解开堆栈,否则很难看出如何避免未定义的行为。
第二个问题的答案“可以再次加入分离的线程”是:
是的,与*_at_thread_exit
系列函数(notify_all_at_thread_exit()
,std::promise::set_value_at_thread_exit()
,...)。
如问题脚注[2]所述,发信号通知条件变量或信号量或原子计数器不足以加入分离的线程(在确保其执行结束发生之前 -在接收之前)通过等待线程表示信号),因为通常在例如notify_all()
条件变量之后将执行更多代码,特别是自动和线程局部对象的析构函数。
运行信号作为线程的最后一件事(在自动和线程局部对象的析构函数发生之后)是_at_thread_exit
函数族的设计目的。
因此,为了避免在没有任何高于标准要求的实现保证的情况下未定义的行为,您需要(手动)使用_at_thread_exit
执行信令的函数连接分离的线程,或者使分离的线程仅执行对于安全的代码信号处理程序也是。
TA贡献1828条经验 获得超13个赞
程序退出后线程的命运是未定义的行为。但是现代操作系统会在关闭它时清理进程创建的所有线程。
在分离时std::thread
,这三个条件将继续保持
*this
不再拥有任何线程joinable()将始终等于false
get_id()将等于std :: thread :: id()
- 3 回答
- 0 关注
- 909 浏览
添加回答
举报