Hol*_*Cat 8 c++ polymorphism multithreading race-condition stdthread
我刚刚得到了一个有趣的比赛条件。考虑以下类:
#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>
class A
{
std::thread th;
std::atomic_bool stop = false;
public:
A() = default;
A(const A &) = delete;
A &operator=(const A &) = delete;
~A()
{
stop.store(true);
th.join();
}
virtual void Step() = 0;
void Start()
{
th = std::thread([this]
{
while (true)
{
if (stop.load())
return;
// Just to help reproduce the race condition.
std::this_thread::sleep_for(std::chrono::milliseconds(50));
Step();
}
});
}
};
struct B : A
{
void Step() override
{
std::cout << "Step!" << std::endl;
}
};
int main()
{
B b;
b.Start();
// Just to help reproduce the race condition.
std::this_thread::sleep_for(std::chrono::milliseconds(110));
}
Run Code Online (Sandbox Code Playgroud)
这会由于纯虚函数调用而崩溃(如果我们忽略数据竞争 UB)。
就在我们进入 的主体之前~A(),在我们停止线程之前,vtable 指针更改为指向A的 vtable,因此下一次调用会Step()崩溃,现在是纯虚拟调用。
这可以通过停止 中的线程来解决~B(),但这意味着每个派生类都必须记住这样做,否则会发生不好的事情。
我希望我能设计A自己来解决这个问题。是否可以?
| 归档时间: |
|
| 查看次数: |
109 次 |
| 最近记录: |