精品专区-精品自拍9-精品自拍三级乱伦-精品自拍视频-精品自拍视频曝光-精品自拍小视频

網(wǎng)站建設(shè)資訊

NEWS

網(wǎng)站建設(shè)資訊

C++如何實(shí)現(xiàn)線程池

這篇文章主要為大家展示了C++如何實(shí)現(xiàn)線程池,內(nèi)容簡(jiǎn)而易懂,希望大家可以學(xué)習(xí)一下,學(xué)習(xí)完之后肯定會(huì)有收獲的,下面讓小編帶大家一起來(lái)看看吧。

創(chuàng)新互聯(lián)成立于2013年,先為哈密等服務(wù)建站,哈密等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為哈密企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。

最近自己寫了一個(gè)線程池。

總的來(lái)說(shuō),線程池就是有一個(gè)任務(wù)隊(duì)列,一個(gè)線程隊(duì)列,線程隊(duì)列不斷地去取任務(wù)隊(duì)列中的任務(wù)來(lái)執(zhí)行,當(dāng)任務(wù)隊(duì)列中為空時(shí),線程阻塞等待新的任務(wù)添加過(guò)來(lái)。

我是用queue來(lái)存放任務(wù),vector存放thread*,然后用condition_variable 來(lái)設(shè)置線程阻塞和喚醒。

下面直接上代碼吧。

線程池類頭文件Thread_Pool.h

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

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

*********************************************/
#pragma once
#ifndef _THREAD_POOL_H_
#define _THREAD_POOL_H_
#include
#include
#include
#include
#include
#include

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

 std::condition_variable cond;//條件量;
 std::vector threads;//線程向量;
 std::atomic IsStart;//原子變量,判斷線程池是否運(yùn)行;
 Task tasks;//任務(wù)變量;
};
#endif

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

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

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

*********************************************/
#include"Thread_Pool.h"
#include
int Task::push(Func func) {
 std::unique_lock 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 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 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();
 }
}

最后是測(cè)試用的main.cpp

#include
#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 << "線程池創(chuàng)建失敗。" << 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;
}

執(zhí)行的效果如下:

C++如何實(shí)現(xiàn)線程池

線程喚醒和阻塞的邏輯就是在線程工作函數(shù)run函數(shù)中,判斷隊(duì)列是否為空,若為空則設(shè)置鎖并調(diào)用condition變量的wait函數(shù),釋放這個(gè)線程中的鎖并阻塞線程,等待任務(wù)隊(duì)列中新的任務(wù)添加進(jìn)來(lái)后,

condition變量通過(guò)notify_one()隨機(jī)喚醒一個(gè)在wait的線程,取出隊(duì)列中的任務(wù)執(zhí)行。

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

IsStart是原子的,所以在寫這個(gè)變量的時(shí)候沒(méi)有另外加鎖。

以上就是關(guān)于C++如何實(shí)現(xiàn)線程池的內(nèi)容,如果你們有學(xué)習(xí)到知識(shí)或者技能,可以把它分享出去讓更多的人看到。


文章標(biāo)題:C++如何實(shí)現(xiàn)線程池
分享網(wǎng)址:http://m.jcarcd.cn/article/pejsgc.html
主站蜘蛛池模板: 三级在线观看 | 日本怡春院天堂 | 国产在线99精品 | 日本黄页网站大全 | 午夜在线亚洲 | 日本三级网址狠狠 | 中文字幕第一页 | 日韩高清在线二区 | 中文字幕一区不 | 国产91色在| 欧美在线 | 国产精品成人 | 日韩女同互慰专区 | 国产91精品一区二 | 国产两性色午夜视频 | 国产91精品调 | 国产基zz视 | 青青久热 | 激情五月天综合 | 国产日韩 | 成人精品视频免费看 | 97色色五月天 | 国产精品冒白 | 国产高清不 | 日本手机在线视频 | 国产美女主播在线 | 欧美一级日韩一级 | 欧美日韩国产亚 | 国产精品情侣 | 国产一区二区网站 | 日韩高清电影 | 国产成自拍亚洲精品 | 日韩一级大片国产 | 欧美日韩高清一道 | 九九在线免费 | 午夜拍拍拍 | 欧美亚洲日韩一区 | 奇米网7777| 国产八区视频在线 | 国产极品尤物在线 | 国产原创 |