github地址:https://github.com/cyzgit/threadpool
0. 编译。
git中有测试代码,test/main.cpp
编译:g++ test/main.cpp thread_pool/thread_pool.cpp -I./ -std=c++11 -lpthread
-
创建线程池。
需传入线程数和最大可容纳任务数。
ThreadPool::ThreadPool(int threadNums, int maxTaskNums){
mThreadNums = threadNums;
mMaxQueSize = maxTaskNums;
mStop = false;
}
2. 启动线程池。
创建mThreadNums个线程,线程执行函数为ThreadFunction,由于在线程函数中,需要访问ThreadPool类中的成员函数,所以需传入this指针(使用bind绑定函数和参数)。
void ThreadPool::Start(){
for(int i = 0; i < mThreadNums; ++ i){
mWorkers.emplace_back(std::bind(&ThreadPool::ThreadFunction, this));
}
}
ThreadFunction为循环从任务队列中取出任务。
void ThreadPool::ThreadFunction(){
while(!mStop){
Task * curTask = nullptr;
{
std::unique_lock<std::mutex> ulock(mMutex);
while(mTaskQueue.empty()){
mCond.wait(ulock, [this] {return !this->mTaskQueue.empty();});
}
curTask = mTaskQueue.front();
mTaskQueue.pop();
}
if(curTask == nullptr){
continue;
}
curTask->SetStatus(StatusRunning);
curTask->Run();
curTask->SetStatus(StatusOver);
}
}
互斥锁和条件变量的使用:
访问任务队列时,使用mutex先加锁,然后判断任务队列中是否有任务,如果为空,则等待条件变量(mCond.wait)。
如果有任务,则去除,并执行task->run()。
3. 添加任务。
bool ThreadPool::AddTask(Task * task){
std::unique_lock<std::mutex> lk(mMutex);
if(mTaskQueue.size() >= mMaxQueSize){
return false;
}
mTaskQueue.push(task);
mCond.notify_all();
return true;
}
每次添加任务之后,都要唤醒条件变量阻塞的线程(调用mCond.notify_all)。