C++中对默认构造线程对象执行join操作后再赋值为何可行?
C++中对默认构造线程对象执行join操作后再赋值为何可行?
嗨,这个问题我来给你掰扯清楚~
先看你提到的这段疑惑代码:
int main() { thread t; if (true == t.joinable()) { t.join(); } t = std::thread(func); return 0; }
核心关键点在于默认构造的std::thread对象的状态:
- 默认构造出来的
std::thread t;,是完全不关联任何实际执行线程的,它处于「非可接合(non-joinable)」状态。所以你代码里的if (true == t.joinable())判断结果是false,里面的t.join()根本就没被执行到!你以为执行了join操作,但这段代码其实啥也没干,就是个空走流程的判断。
然后看后面的赋值操作t = std::thread(func);:
- 这里用的是
std::thread的移动赋值运算符。std::thread(func)会创建一个临时的线程对象,这个临时对象已经和func对应的执行线程绑定了。移动赋值的作用,就是把临时线程的“执行关联权”转移给t——完成后,临时对象就不再关联任何线程,而t就和新创建的那个执行线程绑定了。
最后得给你提个醒:这段代码其实有隐藏的问题!
- main函数返回的时候,
t关联的线程还在运行(你的func是死循环,肯定没结束),而你既没调用t.join()等待线程完成,也没调用t.detach()让它在后台独立运行。这时候std::thread的析构函数会检测到对象还处于可接合状态,直接触发std::terminate()强制终止程序。你觉得它“正常工作”,大概率是没注意到这个隐性的程序终止行为,或者测试环境的某些巧合让你没察觉到异常。
内容来源于stack exchange
相关产品推荐
相关产品推荐

