我有一个小的包装器,它集中了与线程相关的东西:
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参数,但我不知道如何说“使用虚拟纯实现”……
事先谢谢你。
致以敬意,
神秘先生
发布于 2010-07-02 03:02:03
只有当你的程序立即退出时,你的崩溃才会发生:它调用A类的析构函数,在新启动的线程有机会被调度之前完成并调用thread的析构函数。然后线程调用您的虚拟函数,但是类A不再存在,因此它尝试调用线程的do_work(),后者调用纯虚拟功()。下面是带有额外输出的程序:
run() started
run() ended
~A() started
~A() ended
~Thread() started
catch_up() started
do_work() started
pure virtual method called就标准而言,我认为这是未定义的行为,因为当从线程调用do_work()时,对象的引用(boost::ref(*this))已经结束(析构函数调用开始)。
解决方案:让线程在销毁对象之前执行:
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."
发布于 2010-07-02 02:07:12
我在这里有点冒险,但我怀疑问题出在你的线程析构函数上:
virtual ~Thread() {
catch_up();
delete m_thread;
} 如果线程还没有启动,在析构函数中调用catch_up()将使用线程的vtable而不是A的vtable启动boost线程,就像在C++中析构函数的点vtable匹配析构函数类型的作用域,而不是最派生的vtable。
https://stackoverflow.com/questions/3160403
复制相似问题