亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

C++如何實現線程池

發布時間:2020-07-28 15:40:54 來源:億速云 閱讀:201 作者:小豬 欄目:編程語言

這篇文章主要為大家展示了C++如何實現線程池,內容簡而易懂,希望大家可以學習一下,學習完之后肯定會有收獲的,下面讓小編帶大家一起來看看吧。

最近自己寫了一個線程池。

總的來說,線程池就是有一個任務隊列,一個線程隊列,線程隊列不斷地去取任務隊列中的任務來執行,當任務隊列中為空時,線程阻塞等待新的任務添加過來。

我是用queue來存放任務,vector存放thread*,然后用condition_variable 來設置線程阻塞和喚醒。

下面直接上代碼吧。

線程池類頭文件Thread_Pool.h

/********************************************
   線程池頭文件

  Author:十面埋伏但莫慌
  Time:2020/05/03

*********************************************/
#pragma once
#ifndef _THREAD_POOL_H_
#define _THREAD_POOL_H_
#include<thread>
#include<queue>
#include<mutex>
#include<atomic>
#include<vector>
#include<condition_variable>

typedef std::function<void()> Func;//定義線程執行函數類型,方便后面編碼使用。
//任務類
class Task {
public:
 Task() {}
 ~Task() {}
 int push(Func func);//添加任務;
 int getTaskNum();//獲得當前隊列中的任務數;
 Func pop();//取出待執行的任務;
public:
 std::mutex mx;//鎖;
private:
 
 std::queue<Func> tasks;//任務隊列
};
//線程池類
class Thread_Pool {
public:
 Thread_Pool() :IsStart(false) {}
 ~Thread_Pool();
 int addTasks(Func tasks);//添加任務;
 void start();//開啟線程池;
 void stop();//關閉線程池;
 void run();//線程工作函數;
 int getTaskNum();//獲得當前隊列中的任務數;
private:
 static const int maxThreadNum = 3;//最大線程數為3;

 std::condition_variable cond;//條件量;
 std::vector<std::thread*> threads;//線程向量;
 std::atomic<bool> IsStart;//原子變量,判斷線程池是否運行;
 Task tasks;//任務變量;
};
#endif

然后是線程池類成員函數定義文件Thread_Pool.cpp

/********************************************
   線程池CPP文件

  Author:十面埋伏但莫慌
  Time:2020/05/03

*********************************************/
#include"Thread_Pool.h"
#include<iostream>
int Task::push(Func func) {
 std::unique_lock<std::mutex> lock(mx);
 try {
  tasks.emplace(func);
 }
 catch (std::exception e)
 {
  throw e;
  return -1;
 }
 return 0;
}
int Task::getTaskNum()
{
 return tasks.size();
}
Func Task::pop() {
 std::unique_lock<std::mutex> lock(mx);
 Func temp;
 if (tasks.empty())
  return temp;
 else
 {
  temp = tasks.front();
  tasks.pop();
  return temp;
 }
}
int Thread_Pool::addTasks(Func func)
{
 
 int ret = tasks.push(func);
 cond.notify_one();
 return ret;
}
void Thread_Pool::start() {
 if (!IsStart) {
  IsStart = true;
  for (int i = 0; i < maxThreadNum; i++)
  {
   threads.emplace_back(new std::thread(std::bind(&Thread_Pool::run,this)));   
  }
  
 }
}
void Thread_Pool::run()
{
 while (IsStart)
 {
  Func f;
  if (tasks.getTaskNum() == 0 && IsStart)
  {
   std::unique_lock<std::mutex> lock(tasks.mx);
   cond.wait(lock);
  }
  if (tasks.getTaskNum() != 0 && IsStart)
  {
   f = tasks.pop();
   if(f)
    f();
  }

 }
}
int Thread_Pool::getTaskNum() {
 return tasks.getTaskNum();
}
void Thread_Pool::stop() {

  IsStart = false;
  cond.notify_all();
  for (auto T : threads) {
   std::cout << "線程 " << T->get_id() << " 已停止。" << std::endl;
   T->join();
   if (T != nullptr)
   {
    delete T;
    T = nullptr;
   }
  }
 std::cout << "所有線程已停止。" << std::endl;
}
Thread_Pool::~Thread_Pool() {
 if (IsStart)
 {
  stop();
 }
}

最后是測試用的main.cpp

#include<iostream>
#include"Thread_Pool.h"
using namespace std;
void string_out_one() {
 cout << "One!" << endl;
}
void string_out_two() {
 cout << "Two!" << endl;
}
void string_out_three() {
 cout << "Three!" << endl;
}
int main() {
 {
  Thread_Pool Pool;
  try {
   Pool.start();
  }
  catch (std::exception e)
  {
   throw e;
   cout << "線程池創建失敗。" << endl;
  }
  for (int i = 0; i < 50000 ;)
  {  
   if (Pool.getTaskNum() < 1000) {
    Pool.addTasks(string_out_one);
    Pool.addTasks(string_out_two);
    Pool.addTasks(string_out_three);
    std::cout << i++ << std::endl;
   }
  }
  getchar();
 }
 getchar();
 return 0;
}

執行的效果如下:

C++如何實現線程池

線程喚醒和阻塞的邏輯就是在線程工作函數run函數中,判斷隊列是否為空,若為空則設置鎖并調用condition變量的wait函數,釋放這個線程中的鎖并阻塞線程,等待任務隊列中新的任務添加進來后,

condition變量通過notify_one()隨機喚醒一個在wait的線程,取出隊列中的任務執行。

寫這個線程池的過程中碰到的最主要需要注意的就是鎖的使用,在對隊列的寫和釋放時要注意加鎖,在需要阻塞線程時,要注意通過{}設置鎖的范圍。

IsStart是原子的,所以在寫這個變量的時候沒有另外加鎖。

以上就是關于C++如何實現線程池的內容,如果你們有學習到知識或者技能,可以把它分享出去讓更多的人看到。

向AI問一下細節

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

AI

大兴区| 武川县| 甘孜| 碌曲县| 哈密市| 阿勒泰市| 巴南区| 铜川市| 收藏| 渭源县| 子洲县| 仲巴县| 东方市| 宁陕县| 都匀市| 平泉县| 上栗县| 民勤县| 阿拉善左旗| 吉首市| 晋宁县| 扎囊县| 朝阳市| 峨山| 清苑县| 定州市| 关岭| 呼图壁县| 元谋县| 永登县| 三明市| 吉安市| 房产| 天长市| 卓资县| 呼玛县| 贺兰县| 清镇市| 辉南县| 赤壁市| 新平|