我启动了一个基于线程的线程。在这个线程中调用了一个纯虚拟函数。我在派生类中实现它。
#include <iostream>
#include <memory>
#include <thread>
struct Base {
std::unique_ptr<std::thread> th;
virtual void foo() = 0;
void bar() {
th = std::make_unique<std::thread>(
[this](){
foo();
}
);
}
virtual ~Base(){
th->join();
}
};
struct Derived : public Base {
virtual void foo() override {
std::cout << "impl in derived" << std::endl;
}
};
int main() {
Derived d;
d.bar();
return 0;
}然而,在这些代码中,派生对象将在基对象之前解构。
pure virtual method called
terminate called without an active exception
Aborted (core dumped)在这种情况下,如何控制破坏秩序?
发布于 2022-06-22 09:00:50
这是一个并发问题,所发生的是未定义的行为。如果您构建了不同的配置(例如,从Debug切换到发布版),应用程序就会以不同的方式中断是完全可能的。
具体来说,我认为当main完成执行并超出范围时,您的线程才刚刚开始。这将调用所有的析构,最终(在您的实现中),foo指向基类实现(在派生析构函数的末尾),然后main在基析构函数中被阻塞--在调用join。
如何修复:
在一个单独的函数中移动联接并显式调用它:
struct Base {
std::unique_ptr<std::thread> th;
virtual void foo() = 0;
void bar() {
th = std::make_unique<std::thread>(
[this](){
foo();
}
);
}
virtual ~Base() = default;
void join() { th->join(); }
};
int main() {
Derived d;
d.bar();
d.join(); // prevent the destruction of the derived part
// and main blocking before completing the base
// destructor execution.
return 0;
}https://stackoverflow.com/questions/72712133
复制相似问题