Linux 下 C++ 线程池设计与实现
线程池设计
线程池
一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络 sockets 等的数量。
应用场景
- 需要大量的线程来完成任务,且完成任务的时间比较短。比如 WEB 服务器完成网页请求这样的任务,使用线程池技术是非常合适的。因为单个任务小,而任务数量巨大,你可以想象一个热门网站的点击次数。但对于长时间的任务,比如一个 Telnet 连接请求,线程池的优点就不明显了。因为 Telnet 会话时间比线程的创建时间大多了。
- 对性能要求苛刻的应用,比如要求服务器迅速响应客户请求。
- 接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用。突发性大量客户请求,在没有线程池情况下,将产生大量线程,虽然理论上大部分操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限,出现错误。
种类
- 创建固定数量线程池,循环从任务队列中获取任务对象,获取到任务对象后,执行任务对象中的任务接口
- 浮动线程池,其他同上
线程描述与组织
既然是一个线程池,需要创建大量的线程,让线程从任务队列中取数据来执行任务。要对线程做创建,控制,回收,因此需要对线程做管理,如何管理呢?需要能够描述线程和做组织!
好在我们之前做过了对线程的封装,其封装如下:
Thread.hpp
#define get_lwp_id() syscall(SYS_gettid)
using func_t = std::function<void(const std::string& name)>;
const std::string threadnamedefault = "None-Name";
class Thread {
public:
Thread(func_t func, const std::string &name = threadnamedefault)
: _name(name), _func(func), _isrunning(false) {
LOG(LogLevel::INFO) << _name << " create thread obj success";
}
static void *start_routine(void *args) {
Thread *self = static_cast<Thread *>(args);
self->_isrunning = true;
self->_lwpid = get_lwp_id();
self->_func(self->_name);
(( *));
}
{
n = (&_tid, , start_routine, );
(n == ) {
(LogLevel::INFO) << _name << ;
}
}
{
n = (_tid);
()n;
}
{
(!_isrunning) ;
n = (_tid, );
(n == ) {
(LogLevel::INFO) << _name << ;
}
}
~() {
}
:
_isrunning;
_tid;
_lwpid;
std::string _name;
_func;
};


