“纯虚方法调用”实现 boost::thread 包装器接口时
我有一个小包装器,它集中了与线程相关的内容:
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 参数,但我不知道怎么说“使用虚拟纯实现”......
预先感谢。
问候,
神秘先生
I have a small wrapper which centralize what's relative to threads :
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)));
}
};
When I implement it, say with the following :
class A : public Thread {
void work() {}
};
At :
A a; a.run();
I got a runtime termination with a pretty "pure virtual method called" displayed. I think it's the boost::bind argument, but I don't know how to say "Use virtual pure implementation"...
Thanks aforehand.
Regards,
Mister Mystère
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我在这里冒险,但我怀疑问题出在你的 Thread 析构函数上:
如果线程尚未启动,在析构函数中调用
catch_up()
将使用以下命令启动 boost 线程线程的 vtable 而不是 A 的 vtable,就像在 C++ 中,在析构函数处,vtable 与析构函数类型的范围匹配,而不是最派生的 vtable。I'm going out on a limb here, but I suspect the problem is with your Thread destructor:
If the thread hasn't started yet, calling
catch_up()
in the destructor will start the boost thread using Thread's vtable rather than A's, as in C++ at the point of the destructor the vtable matches the scope of the type of the destructor, not the most derived vtable.仅当程序立即退出时才会发生崩溃:它调用 A 类的析构函数,该析构函数完成,并在在新启动的线程有机会被调度之前调用线程的析构函数。然后线程调用你的虚函数,但是类A不再存在,所以它尝试调用Thread的do_work(),它调用纯虚函数work()。这是带有额外输出的程序:
标准方面,我认为这是未定义的行为,因为当引用它时,对象的生命周期已经结束(析构函数调用开始)(
boost::ref(*this)
) 用于从线程调用 do_work() 。解决方案:让线程在销毁对象之前执行:
或者,正如 boost.thread 文档所述,"Boost.Thread 的用户必须确保引用的对象比新创建的执行线程寿命更长。"
Your crash happens only when your program exits immediately: it calls class A's destructor which finishes and calls Thread's destructor before the newly started thread had a chance to be scheduled. The thread then calls your virtual function, but class A no longer exists, so it attemps to call Thread's do_work(), which calls the pure virtual work(). Here's your program with extra outputs:
Standard-wise, I think this is undefined behavior because the object's lifetime has already ended (destructor call began) when a reference to it (
boost::ref(*this)
) was used to call do_work() from the thread.Solution: let your thread execute before you destruct your object:
Or, as boost.thread documentation says, "the user of Boost.Thread must ensure that the referred-to object outlives the newly-created thread of execution."