c++ - 删除 boost::thread 后代

标签 c++ destructor boost-thread

我正在尝试编写一个类,该类将在其对象创建时运行一个线程,并在对象被删除后停止该线程。

class MyThread : public boost::thread {

public:

    MyThread() : bAlive(true) { 
        boost::thread(&MyThread::ThreadFunction,this);
    }

    ~MyThread() {
        {
            boost::unique_lock<boost::mutex> lock(Mutex);
            bAlive=false;
        }
        ConditionVariable.notify_one();
        join();
    }

private:

    volatile bool bAlive;
    boost::mutex Mutex;
    boost::condition_variable ConditionVariable;

    void ThreadFunction() {
        boost::unique_lock<boost::mutex> lock(Mutex);
        while(bAlive) {
            ConditionVariable.timed_wait(lock,boost::get_system_time()+ boost::posix_time::milliseconds(MAX_IDLE));

            /*******************************************
            * Here goes some code executed by a thread * 
            *******************************************/

        }
    }

};

理论上,我想在线程需要完成时立即唤醒它,所以我不得不使用 timed_wait 而不是 Sleep。 这工作正常,直到我尝试删除此类的对象。在大多数情况下,它会正常删除,但偶尔会在 condition_variable.hpp、thread_primitives.hpp 或 crtexe.c 中导致错误。有时我会收到“释放堆 block 3da7a8 在释放后在 3da804 处修改”的通知,有时我不会。是的,我知道 timed_wait 的虚假唤醒,在这种情况下它并不重要。 你能指出我问题的根源吗?我做错了什么?

最佳答案

我明白你想做什么,但它没有像你预期的那样工作:

MyThread foo;

默认构造一个boost::thread(因为MyThread是从boost::thread派生的)。 默认构造函数创建一个引用 Not-a-Thread 的 boost::thread 实例。

MyThread() {
    boost::thread(&MyThread::ThreadFunction,this);
}

实际上是在创建一个不同的线程,而您忽略了返回的对象(有效线程)。

~MyThread() {
    // ...
    join();
}

然后尝试加入默认构造的线程(它会在析构函数中引发异常),而您永远不会加入实际执行工作的线程。


首先,不要派生自boost::thread。创建一个成员变量:

class MyThread {
// ...
private:
    // ...
    boost::thread _thread;
};

在构造函数中,创建一个线程并将其分配给该成员变量:

MyThread() {
    _thread = boost::thread(&MyThread::ThreadFunction,this);
}

并在你的析构函数中调用它的 join()。

~MyThread() {
    // ...
    _thread.join();
}

这应该可以解决您的问题。


但是,如果您只是想在对象被销毁时退出线程(并且不必在它运行时唤醒它),您可以使用不同的方法。删除互斥锁和条件变量并改用中断。这将导致 sleep() 抛出异常,因此您必须捕获它:

void ThreadFunction() {
    try {
        for(;;) {
            boost::this_thread::sleep(boost::posix_time::milliseconds(MAX_IDLE));
            // Here goes some code executed by a thread
        }
    } catch( const boost::thread_interrupted& e ) {
        // ignore exception: thread interrupted, exit function
    }
}

这将在线程中断时立即退出 ThreadFunction。如果不需要线程每个周期都休眠,可以用boost::this_thread::interruption_point()代替。如果线程被中断,这只会抛出异常。

现在您可以简单地在析构函数中中断线程:

MyThread::~MyThread() {
    _thread.interrupt();
    _thread.join();
}

关于c++ - 删除 boost::thread 后代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13323600/

相关文章:

c++ - 如何为所有 C++ IOStream 操纵器通用定义插入运算符?

c++ - 对 `boost::chrono::system_clock::now()' 的 undefined reference - Boost 和 cpp-netlib

shared-ptr - shared_ptr 断言像素!= 0 失败

c++ - std::list::remove 方法是否调用每个已删除元素的析构函数?

C++ 如何在类函数中构造一个对象,执行一些操作并返回值?

c++ - Boost:仿函数中的线程和互斥锁

c++ - 错误:纯虚拟方法称为

c++ - 如何在 C++ 中使用只有一个参数的递归打印从 0 到 N 的序列

c++ - Valgrind 在使用适当的 free() 和 end() 后显示 ncurses 命令的内存泄漏

objective-c - iOS App 在退出时崩溃