Boost线程破坏多态性

boost thread destroys polymorphism

本文关键字:多态性 线程 Boost      更新时间:2023-10-16

复制:"纯虚拟方法调用"当实现boost::线程包装器接口

我正在尝试使用boost线程创建一个更面向对象的线程版本。

所以我创建了一个Thread类:
class Thread {
public:
    Thread() {}
    virtual ~Thread() { thisThread->join(); }
    void start() { thisThread = new boost::thread(&Thread::run, this); }
    virtual void run() {};
private:
    boost::thread *thisThread;
};
这个类在start()中创建线程。像这样:

thisThread = new boost::thread(&Thread::run, this);

问题是,当我创建一个覆盖run()方法的类时,线程调用线程的run()方法,而不是新的run()方法

例如,我有一个类扩展了Thread:
class CmdWorker: public Thread {
public:
    CmdWorker() : Thread() {}
    virtual ~CmdWorker() {}
    void run() { /* deosn't get called by the thread */ }
};

当我做

Thread *thread = new CmdWorker();
thread.start(); //---> calls run() from Thread instead of run() from CmdWorker

但是为了更清楚:

thread.run();  calls the correct run from CmdWorker, (run() is virtual from Runnable)

知道为什么会发生这种情况或者如何修复吗?

注意:我创建了一个函数(与Thread类无关)

void callRun(Thread* thread) {
    thread->run();
}

并将线程创建更改为:

thisThread = new boost::thread(callRun, this);

调试时,我注意到thread指针指向线程类型的对象,而不是CmdWorker

编辑:

测试用例代码:http://ideone.com/fqMLF和http://ideone.com/Tmva1

对象似乎被切片(但这是奇怪的,因为使用指针)

没有给它添加boost

答案就在那个问题里:

pure virtual method called"当实现boost::线程包装器接口

基本上,当boost::thread对象开始运行时,它所运行的对象具有要删除的时间。

必须在销毁对象之前手动调用join方法。

调试时,我注意到线程指针指向a线程类型的对象,而不是CmdWorker

也许CmdWorker对象被切片(即按值复制)成一个Thread对象在你的代码的某个地方?

您是否使用最小的测试用例获得相同的行为?

通过对非虚函数执行&Thread::Run,您将强制从Thread派生的任何类使用Thread基类中指定的函数。试着让Thread::运行一个虚拟void,看看是否能解决你的问题。

从阅读你的更新,你在主线程中调用删除,而线程在另一个开始。根据析构函数和run调用之间的竞争,它将:

  1. 在启动前崩溃,因为虚表被完全破坏
  2. 调用Thread::run(这是纯虚拟的,并且会崩溃)
  3. 调用正确的函数,它是派生类run()

如果您在调用start之后,但在调用delete之前添加对sleep(1)的调用,您会发现它像您预期的那样工作。