上一篇《利用std::atomic实现无锁队列-优快云博客》已经讲清楚了如何实现各种情况下的无锁队列,那么无锁的多线程框架该提上日程。
c++11后,多线程编程已经变得比较简单了,运行时开启一个线程的代价也不是很大,但是语言本身提供的功能还是比较像原料,在复杂的业务需求下,我们需要形成一个多线程的编程框架。
通常情况下,程序中的线程都会赋予某些固定的角色,比如《一个简单易用的轻量化的c++网络库-优快云博客》中,网络线程被赋予的特定的角色,并且持有自己需要管理的数据(网络连接),又比如游戏服务器中经常需要把某些功能或者某些数据交给固定的线程处理;线程除了被赋予特定角色外,他们执行的任务也可能具有不确定性,比如外部提交进来一个std::function。因此有必要对线程进行封装,让他们有自己的名称、持有自己管理的数据、能接受各种任务、能自省(在调用栈的任何位置,能识别自身),让线程变成一个不需要休息的工作者,有活就爬起来干,没有活就一边呆着;相对于单个线程,线程池应设计成竞争式的,即任务到来时,唤醒一个不繁忙的线程来完成工作。
线程的任务队列
按照上述的思路,我们封装的线程对象中,应有自己的一个无锁队列,用于接收外部提交的任务:
TMultiV1Queue<std::function<void()> > mTaskQueue;
这是一个多对一线程安全的队列,主要接收封装好的std::function任务。我们还需要一个让线程休眠和唤醒的事件,我们可以使用std::condition_variable:
void ThreadEvent::Wait(uint32_t uMillisec) {
std::unique_lock<std::mutex> lck(mMutex);
if (!mSignal) mCond.wait_for(lck, std::chrono::milliseconds(uMillisec));
mSignal = false;
}
void ThreadEvent::WaitInfinite() {
std::unique_lock<std::mutex> lck(mMutex);
if (!mSignal) mCond.wait(lck);
mSignal = false;
}
void ThreadEvent::Post() {
std::unique_lock<std::mut

最低0.47元/天 解锁文章
751





