检查我的类的std :: thread成员是否已停止

时间:2017-05-12 19:01:58

标签: c++ multithreading class

我有一个有std :: thread成员的类。我在构造函数中分离它,我想确保当对象被销毁时,线程也会被停止并销毁。

我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:2)

detach std::thread后,您无法控制该线程。 std::thread对象释放它,并且在线程完成或进程(程序)退出之前,不会释放线程的所有资源。如果你想停止一个分离的线程,你必须用某种标志(std::atomic<bool>想到)或std::condition_variable向它发送一个信号,让它自己结束。

如果您希望线程与类一起使用,然后一旦类被销毁,则终止该线程,然后您不想调用detach。相反,你要做的是在析构函数中调用join()来阻止析构函数运行直到线程完成。一旦它完成,那么析构函数将继续,你将知道线程已经结束并且一切都已被清理。

答案 1 :(得分:2)

  

我有一个有std :: thread成员的类

好!

  

我在构造函数

中分离它

好的。这意味着您不希望该类再次管理该线程。没问题。

  

我想确保当对象被销毁时,线程也会被停止并销毁

哦,所以......嗯。你希望班级管理线程?有趣。

不要分离线程。

它实际上是反你想要做的事情并且单独负责你的问题。

答案 2 :(得分:0)

让我们看一个例子,如何处理std::thread以确保在销毁机箱对象时将停止和销毁它:

#include <mutex>
#include <condition_variable>
#include <thread>
#include <atomic>

#include <cstdlib>
#include <ctime>
#include <iostream>

class ThreadTester {
public:
    ThreadTester() : isAlive(true), randomNumber(0) {
        // Start the background operation.
        myThread = std::thread(&ThreadTester::createRandom, this);
    }

    virtual ~ThreadTester() {
        {
            // Stop the running thread.
            std::unique_lock<std::recursive_mutex> lk(mutex);
            isAlive = false;
            condition.notify_all();
        }
        // Join the stopped thread.
        if(myThread.joinable())
            myThread.join();
    }

    int getRandom() const {
        return randomNumber;  
    }

private:
    void createRandom() {
        std::unique_lock<std::recursive_mutex> lk(mutex);

        // Do something with 250ms intervall while the isAlive is true.
        while(isAlive) {
            condition.wait_for(lk, std::chrono::milliseconds(250));
            if(isAlive) {
                randomNumber = rand() % 100;
            }
        }
    }

    std::recursive_mutex mutex;
    std::condition_variable_any condition;
    bool isAlive;
    std::thread myThread;
    std::atomic_int randomNumber;
};

int main() {
    srand(time(NULL));    
    const ThreadTester tester;

    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "Test: " << tester.getRandom() << std::endl;

    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "Test: " << tester.getRandom() << std::endl;

    return 0;
}

我的例子我抓住线程直到它停止,以确保它可以被安全地销毁。我不认为拆分线程是一种很好的做法。