You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

理解C++栈对象分配规则及线程传递移动对象后崩溃问题

问题根因分析

崩溃的直接原因是对std::thread对象执行了错误的操作流程:

  1. 你先调用了thd.detach(),这会将线程的执行权完全交给操作系统,同时当前std::thread对象会和实际执行的线程解除关联,变为*不可联接(joinable)*状态
  2. 之后你又把已经detach的线程对象存入vector,最后遍历vector调用join(),对不可联接的线程执行join操作,C++标准明确规定会抛出std::system_error异常,对应你看到的Invalid argument错误。
代码修复方案

你只需要删掉thd.detach()这一行即可,修改后的循环逻辑如下:

for (int i = 0; i < 5; i++) {
    std::cout << "loop iteration " << i << std::endl;
    thing t(i);
    // 直接构造线程,不需要detach
    std::thread thd(std::bind(handle_thing, i, std::move(t)));
    // 直接存入vector即可
    threads.push_back(std::move(thd));
}

你的栈对象移动传递逻辑本身是完全正确的:std::move将栈上的thing对象转移到std::bind的绑定对象中,再转移到std::thread的内部存储,全程没有悬垂引用,符合你要传递不可拷贝对象的需求。

针对socket传递场景的补充说明

对于不可拷贝的boost::ip::tcp::socket对象,你现在的写法思路完全可用:

  • 循环内栈上构造socket对象
  • 用std::move将socket转移给线程的入口函数,整个过程没有拷贝,只有移动操作,效率很高
  • 不需要调用detach,统一将线程存入vector后join即可;如果不需要等待线程返回才退出主程序,才需要用detach,这种情况就不要再把线程对象存入vector执行join,两种操作二选一即可。

内容的提问来源于stack exchange,提问作者Ihab Awad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 18:15:03