最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于C++17實現(xiàn)的手寫線程池

 更新時間:2024年08月21日 09:32:33   作者:吃我一個平底鍋  
本文主要介紹了基于C++17實現(xiàn)的手寫線程池,自己實現(xiàn)了Any類,Semaphore類以及Result類的開發(fā),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

接著上文,我們使用了基于C++11實現(xiàn)的手寫線程池,自己實現(xiàn)了Any類,Semaphore類以及Result類的開發(fā),其中很多細節(jié)是值得學習的,隨著不斷更新,在C++17中提供future類,使得代碼更加輕量化。接下來我們來看一下源碼剖析:

threadpool.h

在最終版,除去 submitTask 以及 threadFunc 其余部分和基于C++11是一樣的,這里不自定義Any類,Semaphore類以及Result類,使用C++17中提供的future類,并且支持用戶輸入任意類型,任意參數(shù)數(shù)量的任務(wù).
首先,定義了一個Task任務(wù),不確定函數(shù)返回值類型

using Task = std::function<void()>;

submitTask

template<typename Func,typename... Args> //右值引用,引用折疊,可變參

auto submitTask(Func&& func, Args&&... args) -> std::future<decltype(func(args...))>
{
	//打包任務(wù) 放入任務(wù)隊列里面
	using RType = decltype(func(args...));  //返回值類型
	auto task = std::make_shared<std::packaged_task<RType()>>(
		std::bind(std::forward<Func>(func), std::forward<Args>(args)...)); //forward保持左值或者右值特性
	std::future<RType> result = task->get_future(); //把參數(shù)全部綁定到函數(shù)上


	//獲取鎖
	std::unique_lock<std::mutex> lock(taskQueMtx_);


	if (!notFull_.wait_for(lock, std::chrono::seconds(1),
		[&]()->bool {return taskQue_.size() < (size_t)taskQueMaxThresHold_; }))
	{

		std::cerr << "task queue is full,submit task fail." << std::endl;
		auto task = std::make_shared<std::packaged_task<RType()>>(
			[]()->RType { return RType(); }); 
		(*task)(); 
		return task->get_future();;
	}

	taskQue_.emplace([task]() {
		(*task)(); }); 
		
	taskSize_++;


	notEmpty_.notify_all();


	if (poolMode_ == PoolMode::MODE_CACHED
		&& taskSize_ > idleThreadSize_
		&& curThreadSize_ < threadSizeThresHold_)
	{

		std::cout << ">>> create new thread" << std::endl;

		//創(chuàng)建thread線程對象
		auto ptr = std::make_unique<Thread>(std::bind(&ThreadPool::threadFunc, this, std::placeholders::_1));
		//threads_.emplace_back(std::move(ptr)); //資源轉(zhuǎn)移
		int threadId = ptr->getId();
		threads_.emplace(threadId, std::move(ptr));
		threads_[threadId]->start(); //啟動線程

		//修改線程個數(shù)相關(guān)的變量
		curThreadSize_++;
		idleThreadSize_++;
	}

	//返回任務(wù)的Result對象
	return result;


}
  • 為了讓submitTask可以接收任意任務(wù)函數(shù)和任意數(shù)量的參數(shù),我們使用可變參模板編程template<typename Func,typename... Args>;
  • submitTask返回的類型是由decltype推導出來的,func(args…) 參數(shù)傳入函數(shù),通過decltype可以推導出來類型,但是不會計算表達式;
  • 打包任務(wù) 放入任務(wù)隊列里面,使用 decltype(func(args…)); 來確定返回值類型RType;
  • 確定task,把參數(shù)全部綁定到函數(shù)上
  • 把參數(shù)全部綁定到函數(shù)上;
  • 通過future類的get_future(); 獲取返回值

接下來就執(zhí)行任務(wù),由于using Task = std::function<void()>;任務(wù)隊列的任務(wù)沒有返回值,但是上面的task有返回值,所以使用中間層匿名函數(shù)對象,當調(diào)用匿名函數(shù)時,實際上就是調(diào)用(*task)();,task解引用以后就是packaged_task,然后()執(zhí)行了task任務(wù),在線程函數(shù)中,執(zhí)行task()相當于就執(zhí)行了packaged_task對象。

啟動線程,執(zhí)行線程函數(shù)

void threadFunc(int threadid)
{
	auto lastTime = std::chrono::high_resolution_clock().now();
	for (;;)
	{
		Task task;
		{
			//獲取鎖
			std::unique_lock<std::mutex> lock(taskQueMtx_);
			std::cout << "tid:" << std::this_thread::get_id()<< "嘗試獲取任務(wù)..." << std::endl;

			while (taskQue_.size() == 0)
			{

				if (!isPoolRuning_)
				{
					threads_.erase(threadid);
					std::cout << "threadid:" << std::this_thread::get_id()
						<< "exit!" << std::endl;

					exitCond_.notify_all();
					return;
				}

				if (poolMode_ == PoolMode::MODE_CACHED)
				{	//超時返回std::cv_status::timeout
					if (std::cv_status::timeout ==
						notEmpty_.wait_for(lock, std::chrono::seconds(1)))
					{
						auto now = std::chrono::high_resolution_clock().now();
						auto dur = std::chrono::duration_cast<std::chrono::seconds>(now - lastTime);
						if (dur.count() >= THREAD_MAX_IDLE_TIME&& curThreadSize_ > initThreadSize_)
						{
							threads_.erase(threadid);
							curThreadSize_--;
							idleThreadSize_--;

							std::cout << "threadid:" << std::this_thread::get_id()<< "exit!" << std::endl;
							return;
						}
					}
				}
				else
				{
					//等待notEmpty_條件
					notEmpty_.wait(lock);
				}
			}

			idleThreadSize_--;

			std::cout << "tid:" << std::this_thread::get_id()
				<< "獲取任務(wù)成功..." << std::endl;

			//從任務(wù)隊列中取一個任務(wù)出來
			task = taskQue_.front();
			taskQue_.pop();
			taskSize_--;

			//若依然有剩余任務(wù),繼續(xù)通知其他線程執(zhí)行任務(wù)
			if (taskQue_.size() > 0)
			{
				notEmpty_.notify_all();
			}
			notFull_.notify_all();
		}

		if (task != nullptr)
		{
			task(); //執(zhí)行std::function<void()>;
		}
		idleThreadSize_++;

		auto lastTime = std::chrono::high_resolution_clock().now();
	}
}

除去執(zhí)行任務(wù)的地方改變了,其余沒變;

這里取出task,然后task(); 相當于執(zhí)行了(*task)();也就是執(zhí)行了packaged_task對象。

測試文件

#include <iostream>
#include <functional>
#include <thread>
#include <future>
#include <chrono>

#include "threadpool.h"

using namespace std;


int sum1(int a, int b)
{
	std::this_thread::sleep_for(std::chrono::seconds(5));
	return a + b;
}

int sum2(int a, int b,int c)
{
	std::this_thread::sleep_for(std::chrono::seconds(5));
	return a + b + c;
}

int main()
{
	ThreadPool pool;

	//pool.setMode(PoolMode::MODE_CACHED);

	pool.start(2);

	future<int> res1 = pool.submitTask(sum1, 1, 2);
	future<int> res2 = pool.submitTask(sum2, 1, 2,3);
	future<int> res3 = pool.submitTask([](int d, int e)->int {
		int sum = 0;
		for (int i = d; i < e; i++)
			sum += i;
		return sum;
		},1, 100);

	future<int> res4 = pool.submitTask([](int d, int e)->int {
		int sum = 0;
		for (int i = d; i < e; i++)
			sum += i;
		return sum;
		}, 1, 100);

	future<int> res5 = pool.submitTask([](int d, int e)->int {
		int sum = 0;
		for (int i = d; i < e; i++)
			sum += i;
		return sum;
		}, 1, 100);

	cout << res1.get() << endl;
	cout << res2.get() << endl;
	cout << res3.get() << endl;
	cout << res4.get() << endl;
	cout << res5.get() << endl;
}

ThreadPool定義對象,開啟線程,2個線程

這里可以提交任意類型的,任意參數(shù)個數(shù)的任務(wù)以及匿名函數(shù);

在這里插入圖片描述

pool.setMode(PoolMode::MODE_CACHED); 下:

在這里插入圖片描述

好了~ 基于C++17實現(xiàn)的線程池就剖析結(jié)束了,實際上使用了future類以及packaged_task(function函數(shù)對象),方便了我們項目的實現(xiàn),更多相關(guān)C++17 手寫線程池內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言 數(shù)據(jù)結(jié)構(gòu)之數(shù)組模擬實現(xiàn)順序表流程詳解

    C語言 數(shù)據(jù)結(jié)構(gòu)之數(shù)組模擬實現(xiàn)順序表流程詳解

    順序表,全名順序存儲結(jié)構(gòu),是線性表的一種,線性表用于存儲邏輯關(guān)系為“一對一”的數(shù)據(jù),順序表自然也不例外,不僅如此,順序表對數(shù)據(jù)的物理存儲結(jié)構(gòu)也有要求,跟隨下文來具體了解吧
    2021-11-11
  • 代碼講解C++繼承和派生

    代碼講解C++繼承和派生

    在本文中我們通過實例代碼給大家講解下C++繼承和派生相關(guān)知識點,需要的朋友們學習下。
    2019-02-02
  • OpenCV實現(xiàn)拼圖板小游戲

    OpenCV實現(xiàn)拼圖板小游戲

    這篇文章主要為大家詳細介紹了OpenCV實現(xiàn)拼圖板小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • 探究C++中指針與數(shù)組運算符優(yōu)先級

    探究C++中指針與數(shù)組運算符優(yōu)先級

    C++中與指針和數(shù)組相關(guān)的運算符優(yōu)先級,通過實際代碼示例解釋了運算符的左結(jié)合與右結(jié)合方式,以及如何使用圓括號()來改變默認的結(jié)合順序,文章還提供了一個優(yōu)先級表,列出了運算符的優(yōu)先級和結(jié)合性,幫助讀者更好地理解復(fù)雜表達式中運算符的調(diào)用順序
    2024-10-10
  • 從C語言過渡到C++之基本變化

    從C語言過渡到C++之基本變化

    在之前的C++代碼訓練營系列中,我試圖用完成具體項目的方式給大家介紹C++,但后來大家反饋說這樣從C過渡到C++有點跟不上。于是我又專門設(shè)計了這個《從C到C++》的過渡專題,我準備通過10篇文章介紹一下C++和C的重要區(qū)別。
    2017-07-07
  • 利用Matlab實現(xiàn)陰影柱狀圖的繪制

    利用Matlab實現(xiàn)陰影柱狀圖的繪制

    陰影柱狀圖繪制的代碼MATHWORKS上也有,不過是生成圖片后,識別圖像上不同顏色塊并直接修改像素生成陰影線。這樣的生成方式不可逆且自由度較低,所以本文為大家?guī)淼氖且粋€直接畫線條填充的硬畫版本,希望有所幫助
    2022-09-09
  • C++ 內(nèi)聯(lián)函數(shù)inline Function示例詳解

    C++ 內(nèi)聯(lián)函數(shù)inline Function示例詳解

    文章介紹了C++內(nèi)聯(lián)函數(shù)的含義、內(nèi)聯(lián)展開、編譯器何時內(nèi)聯(lián)以及內(nèi)聯(lián)對鏈接和性能的影響,內(nèi)聯(lián)函數(shù)允許在頭文件中定義函數(shù),以避免ODR錯誤,本文給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2025-11-11
  • c++ 對數(shù)器實現(xiàn)示例

    c++ 對數(shù)器實現(xiàn)示例

    對數(shù)器用于在自己的本地平臺驗證算法正確性,本文詳細的介紹了c++ 對數(shù)器實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • C語言 數(shù)據(jù)結(jié)構(gòu)堆排序順序存儲(升序)

    C語言 數(shù)據(jù)結(jié)構(gòu)堆排序順序存儲(升序)

    這篇文章主要介紹了C語言 數(shù)據(jù)結(jié)構(gòu)堆排序順序存儲(升序)的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • C語言基于graphics.h實現(xiàn)圣誕樹

    C語言基于graphics.h實現(xiàn)圣誕樹

    這篇文章主要介紹了圣誕樹代碼,c語言編程,基于graphics.h實現(xiàn),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12

最新評論

屏山县| 金坛市| 定远县| 贞丰县| 乡城县| 泰和县| 湖州市| 澳门| 祥云县| 徐闻县| 宝应县| 新竹市| 津市市| 军事| 慈利县| 杂多县| 婺源县| 天峻县| 永和县| 三明市| 玉门市| 绥化市| 北海市| 正宁县| 鄂托克旗| 上杭县| 墨竹工卡县| 东安县| 县级市| 体育| 容城县| 九江县| 寿光市| 万宁市| 信阳市| 巴南区| 荥阳市| 韶山市| 湘潭县| 兰溪市| 沭阳县|