溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用C++11如何實現(xiàn)線程池

發(fā)布時間:2020-10-28 15:31:52 來源:億速云 閱讀:229 作者:Leah 欄目:開發(fā)技術

這期內(nèi)容當中小編將會給大家?guī)碛嘘P使用C++11如何實現(xiàn)線程池,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

什么是線程池

線程池是一種多線程處理形式,處理過程中將任務添加到隊列,然后在創(chuàng)建線程后自動啟動這些任務。線程池線程都是后臺線程。每個線程都使用默認的堆棧大小,以默認的優(yōu)先級運行,并處于多線程單元中。如果某個線程在托管代碼中空閑(如正在等待某個事件),則線程池將插入另一個輔助線程來使所有處理器保持繁忙。如果所有線程池線程都始終保持繁忙,但隊列中包含掛起的工作,則線程池將在一段時間后創(chuàng)建另一個輔助線程但線程的數(shù)目永遠不會超過最大值。超過最大值的線程可以排隊,但他們要等到其他線程完成后才啟動。

不使用線程池有哪些弊端

創(chuàng)建太多線程,將會浪費一定的資源,有些線程未被充分使用。
銷毀太多線程,將導致之后浪費時間再次創(chuàng)建它們。
創(chuàng)建線程太慢,將會導致長時間的等待,性能變差。
銷毀線程太慢,導致其它線程資源饑餓。

線程池的組成部分

1、線程池管理器(ThreadPoolManager):用于創(chuàng)建并管理線程池
2、工作線程(WorkThread): 線程池中線程
3、任務接口(Task):每個任務必須實現(xiàn)的接口,以供工作線程調(diào)度任務的執(zhí)行。
4、任務隊列:用于存放沒有處理的任務。提供一種緩沖機制

下面直接看代碼實現(xiàn)

ThreadPoolManage.hpp

#pragma once
#include <thread>
#include <vector>
#include <queue>
#include <condition_variable>
#include <mutex>
/*
* 抽象一個任務 根據(jù)自己的需求擴展
*/
class AbsTask 
{
public:
 AbsTask() = default;
 virtual ~AbsTask() = default;
public:
 virtual void run() = 0;
};
template<class _Ty>
class ThreadPoolManage
{
public:
 ThreadPoolManage(unsigned int nMaxThread)
 :mMaxThreadNum(nMaxThread)
 , mThreadStatus(false)
 {
 //啟動的時候就要創(chuàng)建線程
 auto maxNum = std::thread::hardware_concurrency();
 //獲取當前操作系統(tǒng)中CPU的核心數(shù)量 根據(jù)核心數(shù)量來設置 最大工作線程的并發(fā)數(shù)量
 mMaxThreadNum = mMaxThreadNum > maxNum &#63; maxNum : mMaxThreadNum;
 //創(chuàng)建工作線程池
 for (auto i = 0; i < mMaxThreadNum; i++)
 {
  mWorkers.emplace_back([this] {
  while (true)
  {
   std::unique_lock<std::mutex> lock(this->mQueue_mutex);
   this->mCondition.wait(lock, [this]() {return this->mThreadStatus || !this->mTasks.empty(); });
   if (this->mThreadStatus && this->mTasks.empty()) 
   { 
   return; 
   }
   //獲取隊列頭部的任務
   auto task = std::move(this->mTasks.front());
   //任務出隊
   this->mTasks.pop();
   //執(zhí)行工作
   task.run();
  }
  });
 }
 }
 ~ThreadPoolManage()
 {

 {
  std::unique_lock<std::mutex> lock(this->mQueue_mutex);
  this->mThreadStatus = true;
 }
 //通知所有線程起來工作 然后退出
 this->mCondition.notify_all();
 //等待所有線程工作完畢
 for (std::thread& worker : this->mWorkers) 
 {
  if (worker.joinable()) {
  worker.join();
  }
 }
 }
 /*
 * 添加任務到任務隊列
 */
 void addTask(_Ty& task)
 {
 std::unique_lock<std::mutex> lock(this->mQueue_mutex);
 if (mThreadStatus) {
  throw std::runtime_error("workers stop");
 }
 mTasks.emplace(std::move(task));
 mCondition.notify_one();
 }
private:
 /*
 * 工作線程池
 */
 std::vector<std::thread> mWorkers;
 /*
 * 任務隊列
 */
 std::queue<_Ty> mTasks;
 /*
 工作線程的最大并發(fā)數(shù)量
 */
 unsigned int mMaxThreadNum;
 /*
 條件變量 控制線程池中線程的工作狀態(tài)
 */
 std::condition_variable mCondition;
 /*
 * 工作線程鎖
 */
 std::mutex mQueue_mutex;
 /*
 * 控制線程的開關 false 繼續(xù)工作 true 退出線程
 */
 bool mThreadStatus;

};

調(diào)用代碼

main.cpp

#include <iostream>
#include <chrono>
#include "ThreadPool.hpp"
class Task :public AbsTask
{
public:
 void run() override
 {
 std::this_thread::sleep_for(std::chrono::seconds(1));
 std::cout << "works ...... " << std::this_thread::get_id() << std::endl;
 }
};
int main()
{
 ThreadPoolManage<Task> ThreadPool(8);
 for (size_t i = 0; i < 256; i++)
 {
 Task task;
 ThreadPool.addTask(task);
 }
 std::cin.get();
 system("pause");
}

上述就是小編為大家分享的使用C++11如何實現(xiàn)線程池了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI