博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Tars源码分析---线程池实现
阅读量:4166 次
发布时间:2019-05-26

本文共 2433 字,大约阅读时间需要 8 分钟。

前言

Tars底层实现了一个线程池库,主要源代码位于tc_thread_poo.(cpp,h)文件中。线程池队列涉及的核心是工作线程和任务队列的设计。本文基于tars中的实现进行介绍。

TC_Thread

线程池的工作线程类(ThreadWorker)继承自TC_Thread,它是tars实现的线程类,实现原理是基于C++的pthread_create函数。外部用户通过调用TC_Thread的start函数来启动线程,新线程的入口为threadEntry函数,该函数会调用TC_Thread的run函数。run函数是具体的线程执行逻辑,它是一个虚函数

virtual void run() = 0;

因此子类可以通过实现这个函数来控制线程的运行逻辑。我们下面我们根据ThreadWorker实现的run函数来看线程池中的线程的执行逻辑。

ThreadWorker

void TC_ThreadPool::ThreadWorker::run(){    //调用初始化部分    TC_FunctorWrapperInterface *pst = _tpool->get();    if(pst)    {        try        {            (*pst)();        }        catch ( ... )        {        }        delete pst;        pst = NULL;    }    //调用处理部分    while (!_bTerminate)    {        TC_FunctorWrapperInterface *pfw = _tpool->get(this);        if(pfw != NULL)        {            auto_ptr
apfw(pfw); try { (*pfw)(); } catch ( ... ) { } _tpool->idle(this); } } //结束 _tpool->exit();}

可以看到,run函数的执行流可以简单分为两个部分:

1. 在线程启动时,对线程进行初始化
2. while主循环,不断尝试从任务队列中提取任务并执行。

这里的任务是以仿函数对象的形式存在的,这样就可以使得线程不必关心任务的具体实现逻辑,只需要直接调用仿函数即可。下面我们介绍一下线程池的实现,以及对外提供的接口。

TC_ThreadPool

TC_ThreadPool主要维护以下几个成员数据:

/**     * 任务队列     */    TC_ThreadQueue
_jobqueue; /** * 启动任务 */ TC_ThreadQueue
_startqueue; /** * 工作线程 */ std::vector
_jobthread; /** * 繁忙线程 */ std::set
_busthread; /** * 任务队列的锁 */ TC_ThreadLock _tmutex; /** * 是否所有任务都执行完毕 */ bool _bAllDone;

_jobqueue是任务队列,用户通过调用线程池的exec接口向任务队列中添加任务

void exec(const TC_FunctorWrapper
&tf)

_startqueue是中放的是线程启动初始化逻辑。带参start函数负责设置这个队列:

void start(const TC_FunctorWrapper
&tf)

从这个函数的实现可以看到,每个线程的初始化逻辑是一样的。

_jobthread和_busthread是放置线程对象的集合,其中_busthread中存放正在执行任务的线程。

最后,_tmutex是任务锁,_bAllDone是一个状态变量。

TC_ThreadQueue

线程池中的线程在操作TC_ThreadQueue时并没有加锁,这是因为它是一个线程安全的队列。它底层数据存储结构是deque。

TC_ThreadQueue的线程安全性得益于它继承了TC_ThreadLock类:

typedef TC_Monitor
TC_ThreadLock;

该类提供了互斥锁和条件变量来保证多并发操作的安全。通过在TC_ThreadQueue涉及并发竞争问题的操作函数中调用TC_ThreadLock提供的相关操作接口,就可以保证TC_ThreadQueue相应操作函数的线程安全性。

总结

本文以线程池的实现为入口,分别介绍了tars中实现的线程类,线程锁,以及基于线程锁的线程安全对象。所有需要线程安全的对象都可以通过继承TC_ThreadLock基类,然后运用TC_ThreadLock提供的操作函数达到对象的成员数据访问操作的并发安全(当然,这是由于TC_ThreadLock中内置了互斥锁和条件变量)。

转载地址:http://tpqxi.baihongyu.com/

你可能感兴趣的文章
!!!!搜索引擎设计实用教程-以百度为例
查看>>
搜索引擎工作原理(Nutch)
查看>>
七、 基于Nutch主题搜索引擎方案设计
查看>>
垂直搜索引擎 nutch
查看>>
同一进程中的线程究竟共享哪些资源
查看>>
超文本传输协议-HTTP
查看>>
TCP/IP协议分析-协议分层
查看>>
OSI七层网络模型与TCP/IP四层网络模型
查看>>
我在华为工作十年的感悟
查看>>
最全的CSS浏览器兼容问题
查看>>
HTTP协议及过程描述
查看>>
面向站长和网站管理员的Web缓存加速指南[翻译]
查看>>
动态网址与静态网址
查看>>
Apache的工作原理
查看>>
http/apache工作原理
查看>>
什么是Web2.0
查看>>
PHP中$_SERVER的详细用法
查看>>
类与对象(PHP5)之三:静态关键字(Static Keyword)
查看>>
SQL里的EXISTS与in、not exists与not in
查看>>
MySQL字符集及MySQL编码转换
查看>>