簡單版 --? 只能取線程執(zhí)行函數(shù),不能拿到執(zhí)行結(jié)果
轉(zhuǎn)自 https://www.cnblogs.com/guolongzheng/p/13711875.html
thread_pool_manager.h
#pragma once
#include <thread>
#include <vector>
#include <queue>
#include <condition_variable>
#include <mutex>/*
* 抽象一個任務(wù) 根據(jù)自己的需求擴(kuò)展
*/
class AbsTask {
public:
? ? AbsTask() = default;
? ? virtual ~AbsTask() = default;
public:
? ? virtual void run() = 0;
};template<typename _Ty>
class ThreadPoolManage {
public:
? ? ThreadPoolManage(unsigned int nMaxThread)
? ? ? ? : mMaxThreadNum(nMaxThread), mThreadStatus(false)
? ? {
? ? ? ? //啟動的時候就要創(chuàng)建線程
? ? ? ? auto maxNum = std::thread::hardware_concurrency();
? ? ? ? //獲取當(dāng)前操作系統(tǒng)中CPU的核心數(shù)量 根據(jù)核心數(shù)量來設(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(); });
? ? ? ? ? ? ? ? ? ? // 需要退出線程捣辆,并且任務(wù)列表為空欠气,說明該退出了
? ? ? ? ? ? ? ? ? ? if (this->mThreadStatus && this->mTasks.empty()) {
? ? ? ? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? //獲取隊列頭部的任務(wù)
? ? ? ? ? ? ? ? ? ? auto task = std::move(this->mTasks.front());
? ? ? ? ? ? ? ? ? ? //任務(wù)出隊
? ? ? ? ? ? ? ? ? ? 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();
? ? ? ? ? ? }
? ? ? ? }
? ? }? ? /*
? ? * 添加任務(wù)到任務(wù)隊列
? ? */
? ? 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; // 任務(wù)隊列
? ? unsigned int mMaxThreadNum; // 工作線程的最大并發(fā)數(shù)量
? ? std::condition_variable mCondition; // 條件變量 控制線程池中線程的工作狀態(tài)
? ? std::mutex mQueue_mutex; // 工作線程鎖
? ? bool mThreadStatus; // 控制線程的開關(guān), false: 繼續(xù)工作, true: 退出線程
};
thread_pool_manager.cpp
#include <iostream>
#include <chrono>
#include "thread_pool_manager. h"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);
? ? }? ? // 主進(jìn)程這里直接退出不會有問題伤哺,因為退出之前會調(diào)ThreadPoolManage的析構(gòu)隧熙,那里面有join
? ? return 0;
}
升級版 -- 可以拿到執(zhí)行結(jié)果
轉(zhuǎn)自 https://blog.csdn.net/kenjianqi1647/article/details/110834293
說明:
1掏呼、可以拿到線程執(zhí)行結(jié)果的線程池俘陷,肯定會用到模板函數(shù)饶氏,因為不通的任務(wù)的參數(shù)個數(shù)掉伏、參數(shù)類型轰异、返回值類型不一樣憔古。
2仆邓、我們通常的習(xí)慣是類的聲明(包含成員函數(shù))和定義會分開寫在.h文件和.cpp文件里面鲜滩,此時就會遇到一個問題:編譯不過。原因是函數(shù)模板聲明和定義必須寫在一起节值。
注意:函數(shù)模板聲明和定義必須寫在一起
轉(zhuǎn)自https://blog.csdn.net/Currybeefer/article/details/125705223