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)。