C++中线程join与detach并发执行:VS异常是Bug还是未定义行为?
线程同时被join与detach的行为分析
主线程对线程t执行join操作的同时,线程x对同一个t调用detach,对应的代码如下:
#include <thread> #include <iostream> int main(void) { auto t = std::thread([] { std::this_thread::sleep_for( std::chrono::milliseconds(1000) ); } ); auto x = std::thread([&t] { std::this_thread::sleep_for( std::chrono::milliseconds(500) ); if ( t.joinable() ) { std::cout << "detaching t..." << std::endl; t.detach(); } } ); std::cout << "joining t..." << std::endl; t.join(); x.join(); std::cout << "Ok" << std::endl; return 0; }
该程序在GCC的libstdc和Clang的libc环境下能正常运行,输出如下:
joining t... detaching t... Ok
但在Visual Studio中会以非零退出码终止,无法打印"Ok"。
结论
这是程序本身存在未定义行为,而非Visual Studio的Bug。
C++标准明确规定,std::thread的成员函数join()和detach()都不是线程安全的——当多个线程同时对同一个std::thread对象执行join、detach或者其他修改其内部状态的操作时,会触发未定义行为。
在这个例子里,主线程调用t.join()的同时,线程x可能正在调用t.detach(),两者同时修改t的内部状态(比如标记线程是否可join的标志),这种竞态条件直接导致了未定义行为:不同编译器的标准库实现对这种情况的处理逻辑不同,libstdc++/libc++的实现恰好没有崩溃,但Visual Studio的实现则触发了错误终止。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

