線程池是指定線程創建的個數,每個線程只是創建銷燬一次。比起毫無限制的創建線程銷燬線程效率更高。畢竟頻繁的創建銷燬線程會消耗系統資源,而且系統創建線程也是有上限的。
基於上一篇的線程安全隊列實現
class thread_pool
{
private:
atomic_bool done; //原子操作
vector<thread> work_thread;//工作線程
thread_safe_queue<function<void()>> work_queue; //工作隊列
public:
thread_pool(int n);
void submit(function<void()> f);
~thread_pool();
};
thread_pool::thread_pool(int n):done(false)
{
for(int i=0;i<n;i++)
{
work_thread.emplace_back([this](){
for(;;)
{
function<void()> task;
bool bl=this->work_queue.wait_and_pop(task,this->done);
if(bl)
{
//執行任務
task();
}
else
{
//進程結束條件
return ;
}
}
});
}
}
//1 notify_all非常重要,每個任務都notify_one,最終condition_variable.wait會被阻塞。使用notify_all
// 所有的進程都會出發一次wait,故而跳出阻塞,結束線程
thread_pool::~thread_pool()
{
done=true;
work_queue.notify_all();//1
for(auto &worker:work_thread)
{
worker.join();
}
}
void thread_pool::submit(function<void()> f)
{
work_queue.push(f);
}
int main()
{
thread_pool tp(20);
for(int i=0;i<20;i++)
{
tp.submit([i](){
this_thread::sleep_for(std::chrono::seconds(1));
cout<<i;
});
}
}
condition_variable:
是c++11多線程編程中提供的一種同步的機制。成員函數notify_one會通知一個等待線程,而成員函數notify_all會通知所有的等待線程。成員函數wait需要傳遞兩個參數,一個鎖一個函數指針。wait()會去檢查函數的返回值。如果條件不滿足(函數返回false),wait()函數會解鎖互斥量,而且將這個線程置於阻塞或等待狀態。當準備數據的線程調用notify_one()通知條件變量時,處理數據的線程從睡眠狀態中甦醒,重新獲得互斥鎖,並且對條件再次判斷,如果條件滿足,從wait()返回並繼續持有鎖。如果條件不滿足時,線程將對傳入進來的互斥量解鎖,並且重新開始等待。