c++ - 当我希望线程终止时,删除包含正在运行的线程的类是否可以/安全?

标签 c++ c++11 stdthread

这是一个简单的例子:

class worker
{
    std::thread thread1;
    std::thread thread2;

    worker(){}

    start()
    {
        thread1 = std::thread([]()
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(50000));
        });
        thread1.deteach();

        thread2 = std::thread([]()
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(50000));
        });
        thread2.deteach();
    }

    ~worker()
    {
        // Ignore this part! - as per Richard's comment :)
        //thread1.join();   // <-- do I need this at all?
        //thread2.join();   // <-- do I need this at all?
    }
}

int main()
{
    worker *p_worker = new worker();
    p_worker->start();
    std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 1 sec

    delete p_worker;
}
  • 创建 worker
  • 启动持续 50 秒的线程
  • 1 秒后删除 worker(调用析构函数)
  • 在 worker 析构函数中,我重新加入线程(可能应该先检查它们是否可加入?)- 不确定我是否需要这样做。
  • 然后worker被销毁

我看过这个问题:how-do-i-terminate-a-thread-in-c11这表明没有 c11 可移植的方式来终止线程。

问题:

  • 线程是否被完全破坏(没有残留/泄漏)?
    • 如果"is",我是否需要重新加入线程才能销毁它们? 编辑 - Richard 指出这是 N/A
  • 这是明智的做法吗?

最佳答案

如评论中所述,您不能加入分离的线程。 分离线程意味着独立运行。通常,分离一个类拥有的线程是个坏主意。

我建议使用 bool 值来控制线程的生命周期。

例如,你可以这样做:

class worker
{
private:
    std::thread thread1;
    std::atomic<bool> thread1ShouldRun;
    std::thread thread2;
    std::atomic<bool> thread2ShouldRun;

    void workerFunc1() {
        bool threadWorkIsDone = false;
        while (thread1ShouldRun.load()) {
            // Do Stuff
            // Set threadXShouldRun to false when you're done
            // thread1ShouldRun.store(false);
        }
    }

    void workerFunc2() {
        bool threadWorkIsDone = false;
        while (thread2ShouldRun.load()) {
            // Do Stuff
            // Set threadXShouldRun to false when you're done
            // thread2ShouldRun.store(false);
        }
    }

public:
    worker() {}

    void start()
    {
        thread1ShouldRun.store(true);
        thread1 = std::thread(&worker::workerFunc1, this);
        thread2ShouldRun.store(true);
        thread2 = std::thread(&worker::workerFunc2, this);            
    }

    ~worker()
    {
        thread1ShouldRun.store(false);
        // Protection in case you create a worker that you delete and never call start()
        if (thread1.joinable())
            thread1.join();
        thread2ShouldRun.store(false);
        if (thread2.joinable())
            thread2.join();
    }
};

int main()
{
    worker *p_worker = new worker();
    p_worker->start();
    std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 1 sec

    delete p_worker; // Threads will be joined here
}

关于c++ - 当我希望线程终止时,删除包含正在运行的线程的类是否可以/安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49771500/

相关文章:

python - 使用和不使用 `-builtin` 交互 SWIG 模块

c++ - 这是私有(private)构造函数的一个很好的用途吗?

c++ - 将两个 uint32_t 转换为 uint64_t,然后根据位模式而不是值转回 double

c++ - 在C++线程对象中重新绑定(bind)*this, move 构造函数, move 赋值

c++ - 如何在 C++ 中将 std::thread::id 转换为字符串?

c++ - 参数包扩展中评估顺序的问题

c++ - std::map::end 是线程安全的并且保证对于同一个容器它总是相同的吗?

c++ - 重载 R 值引用和代码重复

c++ - memory_order_seq_cst 和 memory_order_acq_rel 有何不同?

c++ - 指针和引用作为线程参数的区别