用 pthread 实现一个 C++ 线程池
线程池到底解决什么问题
线程池本质上是一种复用线程的方式。线程开太多,调度开销会明显上来,缓存局部性也会变差;而线程池的思路很直接:提前准备一组线程,让它们一直等着,从任务队列里取活干。这样就不用为每个短任务反复创建和销毁线程,代价小得多。
它更适合两类场景:一类是短任务很多,比如 Web 服务器处理请求;另一类是请求会突然暴增,但又不希望瞬间把系统拖进大量线程竞争里。像 Telnet 这种长连接任务,线程池的收益就没那么明显了,线程本身的生命周期已经把创建开销摊平了。
常见类型
- 固定数量线程池:线程数先定死,任务来了就排队,线程循环取任务执行。
- 浮动线程池:线程数量可以跟着负载变化,思路更灵活,但实现也更复杂。
线程的封装先做好
线程池不是直接'操作线程',而是先把线程对象封装起来,再由池子统一管理。这样做的好处是,线程的创建、启动、回收都能收在一个接口里,外层不用碰 pthread_create 这些细节。
// 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);
pthread_exit((void *)0);
}
void Start() {
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;
};


