我有一个小包装器,它集中了与线程相关的内容:
class Thread {
protected:
boost::thread *m_thread;
virtual void work() = 0;
void do_work() {
work();
}
public:
Thread() : m_thread(NULL) {}
virtual ~Thread() {
catch_up();
delete m_thread;
}
inline void catch_up() {
if(m_thread != NULL) {
m_thread->join();
}
}
void run() {
m_thread = new boost::thread(boost::bind(&Thread::do_work, boost::ref(*this)));
}
};
当我实施它时,请说明如下:
class A : public Thread {
void work() {}
};
在:
A a; a.run();
我得到了一个运行时终止,显示了一个非常“纯粹的虚拟方法”。我认为这是boost :: bind参数,但我不知道如何说“使用虚拟纯实现”......
先谢谢。
问候,
Mystère先生
答案 0 :(得分:6)
只有当你的程序立即退出时才会发生崩溃:它会调用类A的析构函数完成并在新启动的线程有机会被调度之前调用Thread的析构函数。然后线程调用你的虚函数,但是类A不再存在,所以它试图调用Thread的do_work(),它调用纯虚函数()。这是你的额外输出程序:
run() started
run() ended
~A() started
~A() ended
~Thread() started
catch_up() started
do_work() started
pure virtual method called
标准方面,我认为这是未定义的行为,因为对象的生命周期已经结束(析构函数调用开始),当使用对它的引用(boost::ref(*this)
)从线程调用do_work()时。 p>
解决方案:在破坏对象之前让线程执行:
A a; a.run();
a.catch_up();
或者,正如boost.thread文档所说,"the user of Boost.Thread must ensure that the referred-to object outlives the newly-created thread of execution."
答案 1 :(得分:1)
我在这里出去了,但我怀疑你的Thread析构函数存在问题:
virtual ~Thread() {
catch_up();
delete m_thread;
}
如果线程还没有启动,在析构函数中调用catch_up()
将使用Thread的vtable而不是A来启动boost线程,就像在析构函数中的C ++中vtable匹配类型的范围一样析构函数,而不是最衍生的vtable。