C++11 簡(jiǎn)單實(shí)現(xiàn)線程池的方法
什么是線程池
線程池是一種多線程處理形式,處理過(guò)程中將任務(wù)添加到隊(duì)列,然后在創(chuàng)建線程后自動(dòng)啟動(dòng)這些任務(wù)。線程池線程都是后臺(tái)線程。每個(gè)線程都使用默認(rèn)的堆棧大小,以默認(rèn)的優(yōu)先級(jí)運(yùn)行,并處于多線程單元中。如果某個(gè)線程在托管代碼中空閑(如正在等待某個(gè)事件),則線程池將插入另一個(gè)輔助線程來(lái)使所有處理器保持繁忙。如果所有線程池線程都始終保持繁忙,但隊(duì)列中包含掛起的工作,則線程池將在一段時(shí)間后創(chuàng)建另一個(gè)輔助線程但線程的數(shù)目永遠(yuǎn)不會(huì)超過(guò)最大值。超過(guò)最大值的線程可以排隊(duì),但他們要等到其他線程完成后才啟動(dòng)。
不使用線程池有哪些弊端
創(chuàng)建太多線程,將會(huì)浪費(fèi)一定的資源,有些線程未被充分使用。
銷毀太多線程,將導(dǎo)致之后浪費(fèi)時(shí)間再次創(chuàng)建它們。
創(chuàng)建線程太慢,將會(huì)導(dǎo)致長(zhǎng)時(shí)間的等待,性能變差。
銷毀線程太慢,導(dǎo)致其它線程資源饑餓。
線程池的組成部分
1、線程池管理器(ThreadPoolManager):用于創(chuàng)建并管理線程池
2、工作線程(WorkThread): 線程池中線程
3、任務(wù)接口(Task):每個(gè)任務(wù)必須實(shí)現(xiàn)的接口,以供工作線程調(diào)度任務(wù)的執(zhí)行。
4、任務(wù)隊(duì)列:用于存放沒(méi)有處理的任務(wù)。提供一種緩沖機(jī)制
下面直接看代碼實(shí)現(xiàn)
ThreadPoolManage.hpp
#pragma once
#include <thread>
#include <vector>
#include <queue>
#include <condition_variable>
#include <mutex>
/*
* 抽象一個(gè)任務(wù) 根據(jù)自己的需求擴(kuò)展
*/
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)
{
//啟動(dòng)的時(shí)候就要?jiǎng)?chuàng)建線程
auto maxNum = std::thread::hardware_concurrency();
//獲取當(dāng)前操作系統(tǒng)中CPU的核心數(shù)量 根據(jù)核心數(shù)量來(lái)設(shè)置 最大工作線程的并發(fā)數(shù)量
mMaxThreadNum = mMaxThreadNum > maxNum ? 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;
}
//獲取隊(duì)列頭部的任務(wù)
auto task = std::move(this->mTasks.front());
//任務(wù)出隊(duì)
this->mTasks.pop();
//執(zhí)行工作
task.run();
}
});
}
}
~ThreadPoolManage()
{
{
std::unique_lock<std::mutex> lock(this->mQueue_mutex);
this->mThreadStatus = true;
}
//通知所有線程起來(lái)工作 然后退出
this->mCondition.notify_all();
//等待所有線程工作完畢
for (std::thread& worker : this->mWorkers)
{
if (worker.joinable()) {
worker.join();
}
}
}
/*
* 添加任務(wù)到任務(wù)隊(duì)列
*/
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;
/*
* 任務(wù)隊(duì)列
*/
std::queue<_Ty> mTasks;
/*
工作線程的最大并發(fā)數(shù)量
*/
unsigned int mMaxThreadNum;
/*
條件變量 控制線程池中線程的工作狀態(tài)
*/
std::condition_variable mCondition;
/*
* 工作線程鎖
*/
std::mutex mQueue_mutex;
/*
* 控制線程的開關(guān) 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");
}
到此這篇關(guān)于C++11 簡(jiǎn)單實(shí)現(xiàn)線程池的方法的文章就介紹到這了,更多相關(guān)C++11 線程池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++線程池的簡(jiǎn)單實(shí)現(xiàn)方法
- c++版線程池和任務(wù)池示例
- c++實(shí)現(xiàn)簡(jiǎn)單的線程池
- c++實(shí)現(xiàn)簡(jiǎn)單的線程池
- c++線程池實(shí)現(xiàn)方法
- 基于C++11實(shí)現(xiàn)手寫線程池的示例代碼
- 基于C++17實(shí)現(xiàn)的手寫線程池
- 一種類似JAVA線程池的C++線程池實(shí)現(xiàn)方法
- C++實(shí)現(xiàn)一個(gè)簡(jiǎn)單的線程池的示例代碼
- 使用C++實(shí)現(xiàn)一個(gè)高效的線程池
- C++實(shí)現(xiàn)一個(gè)簡(jiǎn)易線程池的使用小結(jié)
相關(guān)文章
Visual?Studio?2022使用MinGW來(lái)編譯調(diào)試C/C++程序的圖文教程
這篇文章主要介紹了Visual?Studio?2022使用MinGW來(lái)編譯調(diào)試C/C++程序,以實(shí)例來(lái)簡(jiǎn)單介紹一下VS2022中如何使用MinGW來(lái)編譯、調(diào)試C/C++程序,需要的朋友可以參考下2022-08-08
C語(yǔ)言接口與實(shí)現(xiàn)方法實(shí)例詳解
這篇文章主要介紹了C語(yǔ)言接口與實(shí)現(xiàn)方法,包括接口的概念、實(shí)現(xiàn)方法及抽象數(shù)據(jù)類型等,并配合實(shí)例予以說(shuō)明,需要的朋友可以參考下2014-09-09

