ThreadPool Class
如果有问题,欢迎交流!!!
线程池,维护一个业务函数序列,创建线程池并逐一执行业务函数。
数据成员
Condition notEmpty_
条件变量,用于通知线程序列非空
Condition notFull_
条件变量,用于通知线程序列未满
std::deque<std::function<void()>> queue_
业务函数序列
mutable MutexLock mutex_
锁,保护条件变量
notEmpty_
、notFull_
和业务函数序列queue_
string name_
线程池名,主要用于输出错误信息、和给子线程命名(
ThreadPool::start
)
std::function<void()>> threadInitCallback_
由线程池所在线程自己执行的函数,所以它是干嘛的?。在
ThreadPool::setThreadInitCallback()
中设置。
std::vector<std::unique_ptr<muduo::Thread>> threads_
线程序列
size_t maxQueueSize_
线程序列的最大长度,如果为0(实际上代码中是小于等于0),则长度不限。
bool running_
线程池是否在执行业务函数,初始化为
false
,在创建子线程开始执行时(ThreadPool::start()
)中置为true
;在停止线程池运行时(ThreadPool::stop()
)中置为false
。
函数成员
ThreadPool()
初始化各个变量,其中
maxQueueSize_
初始化为 0 0 0。之后可以通过ThreadPool::setMaxQueueSize
重新设置。
~ThreadPool()
析构函数,检查
running_
为真后,调用ThreadPool::stop()
void start(int numThreads)
创建指定数量(
numThreads
)的线程类Thread Class
,设置ThreadPool::runInThread
为子线程的业务函数,并开始执行。如果numThreads==0
且threadInitCallback_
不为空,则调用threadInitCallback_()
。
void stop()
终止线程池的运行:设
running_
为false
,并通过notEmpty_
和notFull_
唤醒所有阻塞在对应条件变量上的线程。对于阻塞在notEmpty_
和notFull_
上的线程,被唤醒后,基本都会检查running_
的状态(ThreadPool::take()
就不检查,但是没影响),如果为false
则直接返回。之后对于每一个线程调用Thread::join()
。
void run(std::Function<void()> task)
运行
task
函数。如果线程池为空,则由调用线程直接运行task
。不然将其插入到业务函数序列。并通过notEmpty_.notify
唤醒一个阻塞在notEmpty()
上的线程。
关于ThreadPool::stop
如何发挥作用:在插入之前,要检查队列是否已满,如果已满则要阻塞在notFull_.wait
上。之后还要检查是否处于运行状态(running_==true
),之后才能决定是否插入。
std::Function<void> take()
获取业务函数序列
queue_
,序列头的业务函数。如果队列为空且处于running_==true
的状态,则要阻塞在notEmpty_.wait()
上。不然,则获取序列头的业务函数,并通过notFull_.notify()
唤醒一个阻塞在notFUll_
上的线程。
bool isFull()
判断线程序列是否已满
void runInThread()
先执行一下
threadInitCallback_
,然后获取业务序列的函数(ThreadPool::take()
),并执行。如果出现异常,则捕获并输出。