在ethereum项目中Worker
类是许多类的基类,子类们继承Worker
类严格来说并不是is-a的关系,而是复用Worker类中的代码,因此可以说Worker
类是一份公用代码类,那么是什么代码这么重要呢?
在Worker类中我们直接来看其成员,可以看到有两个重要的成员变量:
std::unique_ptr<std::thread> m_work;
mutable std::condition_variable m_state_notifier;
看到这里经验丰富的程序员们应该就能想到这个是经典的生产消费者队列的C++11实现方式,还不了解生产消费者队列的同学可以暂停一下,先搜索一下相关知识再继续。
然后我们再来看两个重要的成员函数:
void startWorking();
void stopWorking();
这个其实就是启动和停止m_work
这个线程了。
在startWorking()
函数内部我们能看到线程的初始化过程,线程函数体用的是lambda表达式,其中最重要的一段我列出来:
try
{
startedWorking();
workLoop();
doneWorking();
}
catch (std::exception const& _e)
{
cwarn << "Exception thrown in Worker thread: " << _e.what();
}
这个线程最重要的是执行了这三个操作,startedWorking()
用于workLoop()
前的准备工作,doneWorking()
用于workLoop()
后的收尾工资,workLoop()
内部用一个循环调用了doWork()
来做实际的工作:
void Worker::workLoop()
{
while (m_state == WorkerState::Started)
{
if (m_idleWaitMs)
this_thread::sleep_for(chrono::milliseconds(m_idleWaitMs));
doWork();
}
}
我们再来看这几个函数的定义:
virtual void startedWorking() {}
virtual void doWork() {}
virtual void workLoop();
virtual void doneWorking() {}
可以看到除了workLoop()
有一个默认的实现外,其他函数体都是空的,子类们通过重新实现这几个函数来实现具体的功能,后面我们会看到这些子类们是怎么做的。
网友评论