【发布时间】:2018-01-25 12:24:43
【问题描述】:
我有这个基类:
class Base {
public:
Base();
virtual ~Base();
protected:
virtual on_next_item(std::string& item) = 0;
private:
void read_loop();
};
还有这个派生类:
class Derived : public Base {
public:
Derived();
virtual ~Derived();
protected:
void on_next_item(std::string& item) override;
};
在Base 类构造函数中,我正在启动一个线程,该线程从套接字读取并调用在派生类上调用的on_next_item()。
在Base 析构函数中,读取器线程通过原子标志停止。
但有时read_loop 仍然调用on_next_item,我得到一个“调用纯虚函数!”错误。我假设我在比赛条件下跑步:
子类(对象)已被破坏,因此不再注册该函数。
有解决这种竞争条件的正确方法吗?
为了完整起见,这里是阅读器循环:
while (running.load())
{
string item = read();
if (running.load())
{
on_text_item(item);
}
}
Base 类析构函数中的运行标志切换为 false。
编辑(完整的运行示例,在issue中必须执行多次才能运行):
#include <atomic>
#include <boost/thread/thread.hpp>
#include <boost/chrono.hpp>
#include <iostream>
class Base
{
public:
Base() : running(true)
{
readerThread = new boost::thread(&Base::read_loop, this);
}
virtual ~Base()
{
running = false;
delete readerThread;
readerThread = nullptr;
}
protected:
virtual void on_next_item(std::string &item) = 0;
private:
boost::thread *readerThread;
void read_loop()
{
std::string element = "Element";
while (running.load())
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(2));
on_next_item(element);
}
}
std::atomic_bool running;
};
class Derived : public Base
{
public:
Derived() : Base()
{
}
virtual ~Derived()
{
}
protected:
virtual void on_next_item(std::string &item)
{
std::cout << "On Next Item " << item << std::endl;
}
};
void constAndDestruct()
{
Derived d;
boost::this_thread::sleep_for(boost::chrono::seconds(2));
}
int main(int argc, char **argv)
{
constAndDestruct();
boost::this_thread::sleep_for(boost::chrono::seconds(2));
}
谢谢!
【问题讨论】:
-
能否像往常一样提供minimal reproducible example。其他任何事情都会导致纯粹的猜测。
-
您可以将逻辑从
Base的析构函数移到成员函数中。或者这对你不起作用? -
在构造函数中创建线程似乎不是一个好主意。同样在基类构造函数中,对象还没有完全形成(派生还不存在)。 stackoverflow.com/questions/30258639/…
-
derived part is destructed before the base destructor gets called.该功能是否需要是纯虚拟的?如果您使基本实现成为无操作,那么如果在派生部分被破坏后调用它就不是问题
-
@Soccertrash 是的,这就是我的意思:
virtual void on_next_item(std::string &item) { }
标签: c++ multithreading