我看到一个问题,即调用 boost 的线程-> 加入析构函数会导致死锁。我不明白为什么,而且我不太热衷于在项目中保留正常工作的代码(我不明白为什么会这样)。
类声明(为简洁起见,我删除了 try/catch 的 run() 方法:根据 boost 线程文档,使用或不使用它的结果应该相同):
class B
{
public:
void operator()(){run();}
void run();
void shutdown();
~B();
B();
boost::thread *thr;
bool shutdown_requested;
};
void B::shutdown()
{
shutdown_requested = true;
if (thr != NULL)
{
thr->interrupt();
thr->join(); // deadlock occurs here!
delete thr;
thr = NULL;
}
}
B::~B()
{
shutdown();
}
B::B()
{
thr = new boost::thread(boost::ref(*this));
}
void B::run()
{
while (!shutdown_requested)
{
boost::xtime xt;
boost::xtime_get(&xt, boost::TIME_UTC);
xt.sec += 30;
boost::this_thread::sleep(xt);
}
}
无效的片段:
int main()
{
B *b = new B;
Sleep(5000);
printf("deleting \n");fflush(stdout);
// b->shutdown();
delete b;
printf("done\n");fflush(stdout);
return 0;
}
有效的片段:
int main()
{
B *b = new B;
Sleep(5000);
printf("deleting \n");fflush(stdout);
b->shutdown();
delete b;
printf("done\n");fflush(stdout);
return 0;
}
我认为这种行为的原因与 boost 文档的这段代码有关:
the user of Boost.Thread must ensure that the referred-to object outlives the newly-created thread of execution.
但我真的不明白为什么死锁 - 加入线程不会调用 B 上的析构函数,并且当 run() 方法应该退出时对象本身不会被删除。
最佳答案
我发现了问题所在:它归结为过度热心的程序员。
我最初使用 DUMA ( http://sourceforge.net/projects/duma/ ) 编译了我的项目,以查看我对当前模块的实现是否没有泄漏。不幸的是,我的测试沙箱也启用了 duma 设置,直到我在调试器中单步执行代码时我才意识到这一点。
删除所有内存泄漏检测后,一切都按预期进行。
关于c++ - 在析构函数中加入一个 boost::thread 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1660765/