Rob*_*Lew 3 c++ multithreading
我在基于线程中启动了一个线程。该线程中调用了一个纯虚函数。我在派生类中实现它。
#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;
}
Run Code Online (Sandbox Code Playgroud)
但是,在这些代码中,派生对象将在基础对象之前解构。
pure virtual method called
terminate called without an active exception
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)
这种情况下如何控制销毁顺序呢?
这是一个并发问题,发生的是未定义的行为。如果您构建不同的配置(例如,从调试切换到发布构建),应用程序完全有可能会出现不同的情况。
具体来说,我相信当 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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
83 次 |
| 最近记录: |