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

当希望线程终止时,删除包含运行中线程的类是否安全?

关于删除包含运行中线程的类是否安全的问题分析

首先直接给结论:这种做法既不可行也不安全,咱们结合你的代码慢慢说清楚。

先看你代码里的操作:你启动线程后调用了detach(),这一步会把线程和std::thread对象解绑——意思是,线程会在后台独立运行,哪怕worker对象被销毁,这两个std::thread成员析构时也不会有问题(因为detach过的线程对象析构不会触发std::terminate)。但问题出在这几个地方:

  1. 线程不受控,无法确保终止
    detach之后,你完全失去了对这两个线程的控制权:没办法用join()等待它们结束,也没有标准的安全方式主动终止线程。这意味着哪怕你销毁了worker对象,这两个线程还会继续跑满50秒才结束,期间你完全没法干预。

  2. 潜在的未定义行为风险
    如果你的线程函数里访问了worker类的成员变量(哪怕现在示例里没有,实际场景大概率会有),那当worker对象被销毁后,这些成员变量已经被释放,线程再去访问就会触发内存错误、野指针等未定义行为,程序随时可能崩溃或者出现诡异的bug。

再说说你析构函数里的疑问:join()到底要不要?

  • 如果你的线程没有调用detach(),那必须在std::thread对象析构前调用join()或者detach(),否则std::thread的析构函数会直接调用std::terminate(),程序直接崩溃。
  • 但你这里已经detach了,所以析构时不用join也不会崩溃,但这根本不是解决“希望线程终止”的办法。

正确的做法应该是这样

想要安全地让线程终止并销毁类对象,你需要给线程一个“停止信号”,让线程主动退出,然后等待它结束,再销毁对象。比如用原子变量做停止标志:

#include <thread>
#include <atomic>
#include <chrono>

class worker {
    std::thread thread1;
    std::thread thread2;
    std::atomic<bool> stop_flag{false}; // 原子变量保证线程间同步

public:
    worker() {}
    void start() {
        thread1 = std::thread([this]() {
            while (!stop_flag.load()) {
                // 这里做线程的实际工作
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
            }
        });
        thread2 = std::thread([this]() {
            while (!stop_flag.load()) {
                // 这里做线程的实际工作
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
            }
        });
    }
    ~worker() {
        stop_flag.store(true); // 通知线程可以停止了
        // 检查线程是否可join,避免重复join或者join未启动的线程
        if (thread1.joinable()) {
            thread1.join(); // 等待线程1完全退出
        }
        if (thread2.joinable()) {
            thread2.join(); // 等待线程2完全退出
        }
    }
};

最后总结一下

  • 直接销毁包含detach线程的类对象,虽然不会立刻崩溃,但线程会继续运行,且存在访问已销毁对象的风险,完全不符合你“希望线程终止”的需求。
  • 安全的方式是通过同步机制(比如原子标志、条件变量)让线程主动退出,然后调用join()等待线程结束,再让类对象析构,这样才能确保线程和类的生命周期正确衔接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:37:36