【发布时间】:2017-06-12 12:28:02
【问题描述】:
假设我开始一个std::thread 然后detach() 它,所以线程继续执行,即使曾经代表它的std::thread 超出范围。
进一步假设程序没有可靠的协议来加入分离线程1,所以当main()退出时分离线程仍然运行。
我在标准中找不到任何内容(更准确地说,在 N3797 C++14 草案中),它描述了应该发生的事情,1.10 和 30.3 都没有包含相关的措辞。
1 另一个可能等效的问题是:“分离的线程是否可以再次加入”,因为无论您发明什么协议来加入,信号部分都必须在线程仍在运行,并且操作系统调度程序可能决定在执行信号后立即让线程休眠一个小时,而接收端无法可靠地检测到线程实际上已完成。
如果在运行分离线程的情况下用完main() 是未定义的行为,那么任何使用std::thread::detach() 都是未定义的行为,除非主线程永远不会退出2。
因此,在运行分离线程的情况下用完main() 必须具有已定义 效果。问题是:在哪里(在 C++ 标准中,不是 POSIX,不是 OS 文档,...)是那些定义的效果。
2 无法加入分离的线程(在std::thread::join() 的意义上)。您可以等待来自分离线程的结果(例如,通过来自std::packaged_task 的未来,或通过计数信号量或标志和条件变量),但这并不能保证 线程已完成执行。实际上,除非您将信号部分放入线程的第一个自动对象的析构函数中,否则 通常会有代码(析构函数)在信号发出 之后运行代码。如果操作系统调度主线程在分离线程完成运行所述析构函数之前消耗结果并退出,那么^Wi定义会发生什么?
【问题讨论】:
-
我只能在 [basic.start.term]/4 中找到一个非常模糊的非强制性注释:“在调用
std::exit或退出main之前终止每个线程就足够了,但不是必要的,以满足这些要求。” (整段可能相关)另见 [support.start.term]/8(main返回时调用std::exit)
标签: c++ multithreading c++11 exit stdthread