gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 23:07:14 28 4
gpt4 key购买 nike

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

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/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com