std::thread析构函数何时被调用?结合Stroustrup示例的疑问
关于std::thread析构函数触发程序终止的疑问
我在Bjarne Stroustrup所著《The C++ Programming Language》中看到一段std::thread基础用法示例,感到困惑。示例代码如下:
void run(int i, int n) // warning: really poor code { thread t1 {f}; thread t2; vector<Foo> v; // ... if (i<n) { thread t3 {g}; // ... t2 = move(t3); // move t3 to outer scope } v[i] = Foo{}; // might throw // ... t1.join(); t2.join(); }
Stroustrup提到:我们可能永远无法执行到末尾的两个join(),这种情况下t1的析构函数会终止程序。但我不解的是,t1未超出作用域,也无显式delete调用,其析构函数何时会被调用?我已尝试修改代码运行,但仍未找到原因。
解答
核心原因是std::thread的析构规则:当一个std::thread对象处于**可结合(joinable)**状态时(即未调用过join()或detach()),它的析构函数会直接调用std::terminate()终止整个程序。
回到代码场景:
- 当
v[i] = Foo{}抛出异常时,程序会立即进入异常处理流程,跳过后续的t1.join()和t2.join()语句。 - 此时函数
run的局部变量会按逆序被销毁(从最后创建的变量开始),t1作为局部变量,会在这个过程中被销毁。 - 而
t1自创建后一直处于可结合状态(没有机会执行join()),因此它的析构函数触发std::terminate(),直接终止程序。
简单来说:异常导致函数提前退出,局部变量t1在函数退出时被销毁,而此时t1还未被join/detach,触发了std::thread的终止逻辑。
内容的提问来源于stack exchange,提问作者Rustam Belyalov
相关产品推荐
相关产品推荐

