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

基于C++11實(shí)現(xiàn)手寫(xiě)線(xiàn)程池的示例代碼

 更新時(shí)間:2024年08月21日 09:32:51   作者:吃我一個(gè)平底鍋  
在實(shí)際的項(xiàng)目中,使用線(xiàn)程池是非常廣泛的,本文主要介紹了基于C++11實(shí)現(xiàn)手寫(xiě)線(xiàn)程池的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

在實(shí)際的項(xiàng)目中,使用線(xiàn)程池是非常廣泛的,所以最近學(xué)習(xí)了線(xiàn)程池的開(kāi)發(fā),在此做一個(gè)總結(jié)。
源碼:https://github.com/Cheeron955/Handwriting-threadpool-based-on-C-17

項(xiàng)目介紹

項(xiàng)目分為兩個(gè)部分,在初版的時(shí)候,使用了C++11中的知識(shí),自己實(shí)現(xiàn)了Any類(lèi),Semaphore類(lèi)以及Result類(lèi)的開(kāi)發(fā),代碼比較繞,但是有很多細(xì)節(jié)是值得學(xué)習(xí)的;最終版使用了C++17提供的future類(lèi),使得代碼輕量化。接下來(lái)先看初版:

test.cpp

先從test.cpp開(kāi)始剖析項(xiàng)目構(gòu)造:

#include <iostream>
#include <chrono>
#include <thread>

#include "threadpool.h"

using ULong = unsigned long long;

class MyTask : public Task
{
public:
	MyTask(int begin, int end)
		:begin_(begin)
		,end_(end)
	{
		
	}

	Any run() 
	{
		std::cout << "tid:" << std::this_thread::get_id() << "begin!" << std::endl;
		std::this_thread::sleep_for(std::chrono::seconds(3));
		ULong sum = 0;
		for (ULong i = begin_; i < end_; i++)
		{
			sum += i;
		}

		std::cout << "tid:" << std::this_thread::get_id() << "end!" << std::endl;
		return sum;
	}
private:
	int begin_;
	int end_;
};
int main()
{
	{
		ThreadPool pool;
		pool.setMode(PoolMode::MODE_CACHED);
		pool.start(4);

		Result res1 = pool.submitTask(std::make_shared<MyTask>(1, 1000000));
		Result res2 = pool.submitTask(std::make_shared<MyTask>(1, 1000000));
		pool.submitTask(std::make_shared<MyTask>(1, 1000000));
		pool.submitTask(std::make_shared<MyTask>(1, 1000000));
		pool.submitTask(std::make_shared<MyTask>(1, 1000000));
		pool.submitTask(std::make_shared<MyTask>(1, 1000000));
		ULong sum1 = res1.get().cast_<ULong>();
		std::cout << sum1 << std::endl;
	}
	
	std::cout << "main over!" << std::endl;
	getchar();

}

在main函數(shù)中,創(chuàng)建了一個(gè)ThreadPool對(duì)象,進(jìn)入ThreadPool中:

ThreadPool

重要成員變量

std::unordered_map<int, std::unique_ptr<Thread>> threads_;

//初始的線(xiàn)程數(shù)量 
int initThreadSize_;

//記錄當(dāng)前線(xiàn)程池里面線(xiàn)程的總數(shù)量
std::atomic_int curThreadSize_;

//線(xiàn)程數(shù)量上限閾值
int threadSizeThresHold_;

//記錄空閑線(xiàn)程的數(shù)量
std::atomic_int idleThreadSize_;

//任務(wù)隊(duì)列
std::queue<std::shared_ptr<Task>> taskQue_;

//任務(wù)數(shù)量 需要保證線(xiàn)程安全
std::atomic_int taskSize_;

//任務(wù)隊(duì)列數(shù)量上限閾值
int taskQueMaxThresHold_;

//任務(wù)隊(duì)列互斥鎖,保證任務(wù)隊(duì)列的線(xiàn)程安全
std::mutex taskQueMtx_;

//表示任務(wù)隊(duì)列不滿(mǎn)
std::condition_variable notFull_;

//表示任務(wù)隊(duì)列不空
std::condition_variable notEmpty_;

//等待線(xiàn)程資源全部回收
std::condition_variable exitCond_;

//當(dāng)前線(xiàn)程池的工作模式
PoolMode poolMode_;

//表示當(dāng)前線(xiàn)程池的啟動(dòng)狀態(tài)
std::atomic_bool isPoolRuning_;

const int TASK_MAX_THRESHHOLD = INT32_MAX;
const int THREAD_MAX_THRESHHOLD = 100;
const int THREAD_MAX_IDLE_TIME = 60; //60s

具體含義請(qǐng)看代碼中注釋

重要成員函數(shù)

構(gòu)造函數(shù)

//線(xiàn)程池構(gòu)造
ThreadPool::ThreadPool()
	: initThreadSize_(4)
	, taskSize_(0)
	, idleThreadSize_(0)
	, curThreadSize_(0)
	, threadSizeThresHold_(THREAD_MAX_THRESHHOLD)
	, taskQueMaxThresHold_(TASK_MAX_THRESHHOLD)
	, poolMode_(PoolMode::MODE_FIXED)
	, isPoolRuning_(false)
{
}
  • 進(jìn)行了一系列的初始化,包括線(xiàn)程數(shù)量,闕值等等

析構(gòu)函數(shù)

ThreadPool::~ThreadPool()
{
	isPoolRuning_ = false;
	//notEmpty_.notify_all();//把等待的叫醒 進(jìn)入阻塞 會(huì)死鎖

	std::unique_lock<std::mutex> lock(taskQueMtx_);
	//等待線(xiàn)程池里面所有的線(xiàn)程返回用戶(hù)調(diào)用ThreadPool退出 兩種狀態(tài):阻塞 正在執(zhí)行任務(wù)中
	notEmpty_.notify_all();//把等待的叫醒 進(jìn)入阻塞
	exitCond_.wait(lock, [&]()->bool {return threads_.size() == 0; });
}
  • 析構(gòu)函數(shù)中,主要是回收線(xiàn)程池的資源,但是這里要注意notEmpty_.notify_all();位置,如果在獲得鎖之前就喚醒,可能會(huì)發(fā)生死鎖問(wèn)題,這個(gè)在下面還會(huì)在提到。

設(shè)置線(xiàn)程池的工作模式

void ThreadPool::setMode(PoolMode mode)
{
	if (checkRunningState()) return;
	poolMode_ = mode;
}

設(shè)置task任務(wù)隊(duì)列上限閾值

void ThreadPool::setTaskQueMaxThreshHold(int threshhold)
{
	if (checkRunningState()) return;
	taskQueMaxThresHold_ = threshhold;
}

設(shè)置線(xiàn)程池的工作模式,支持fixed以及cached模式

enum class PoolMode
{
	MODE_FIXED, //固定數(shù)量的線(xiàn)程
	MODE_CACHED, //線(xiàn)程數(shù)量可動(dòng)態(tài)增長(zhǎng)
};

void ThreadPool::setMode(PoolMode mode)
{
	if (checkRunningState()) return;
	poolMode_ = mode;
}

設(shè)置task任務(wù)隊(duì)列上限閾值

void ThreadPool::setTaskQueMaxThreshHold(int threshhold)
{
	if (checkRunningState()) return;
	taskQueMaxThresHold_ = threshhold;
}

設(shè)置線(xiàn)程池cached模式下線(xiàn)程閾值

void ThreadPool::setThreadSizeThreshHold(int threshhold)
{
	if (checkRunningState()) return;

	if (poolMode_ == PoolMode::MODE_CACHED)
	{
		threadSizeThresHold_ = threshhold;
	}
}

給線(xiàn)程池提交任務(wù),這是重中之重,用來(lái)生產(chǎn)任務(wù)

Result ThreadPool::submitTask(std::shared_ptr<Task> sp)
{
	//獲取鎖
	std::unique_lock<std::mutex> lock(taskQueMtx_);

	//線(xiàn)程通信 等待任務(wù)隊(duì)列有空余 并且用戶(hù)提交任務(wù)最長(zhǎng)不能阻塞超過(guò)1s 否則判斷提交失敗,返回
	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;
		return Result(sp, false);
	}

	//如果有空余,把任務(wù)放入任務(wù)隊(duì)列中
	taskQue_.emplace(sp);
	taskSize_++;

	notEmpty_.notify_all();

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

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

		//創(chuàng)建thread線(xiàn)程對(duì)象
		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(); //啟動(dòng)線(xiàn)程

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

	//返回任務(wù)的Result對(duì)象
	return Result(sp);
}
  • 在submitTask函數(shù)中,首先這是生產(chǎn)任務(wù)的函數(shù),所以我們要保證線(xiàn)程安全,獲取鎖;
  • 考慮到了如果有耗時(shí)嚴(yán)重的任務(wù)一直占用,線(xiàn)程,導(dǎo)致提交任務(wù)一直失敗,所以等待1s提交失敗以后會(huì)通知用戶(hù);
  • 此時(shí)隊(duì)列里面的任務(wù)沒(méi)有超過(guò)闕值,就把任務(wù)放入任務(wù)隊(duì)列中,更新任務(wù)數(shù);
  • 因?yàn)樾路帕巳蝿?wù),任務(wù)隊(duì)列不空了,在notEmpty_上進(jìn)行通知,趕快分配線(xiàn)程執(zhí)行任務(wù);
  • cached模式下,需要根據(jù)任務(wù)數(shù)量和空閑線(xiàn)程的數(shù)量,判斷是否需要?jiǎng)?chuàng)建新的線(xiàn)程出來(lái),如果任務(wù)數(shù)大于現(xiàn)有的空閑線(xiàn)程數(shù)并且沒(méi)有超過(guò)闕值,就增加線(xiàn)程,修改相關(guān)數(shù)量;
  • 返回任務(wù)的Result對(duì)象

開(kāi)啟線(xiàn)程池

void ThreadPool::start(int initThreadSize)
{
	//設(shè)置線(xiàn)程池的運(yùn)行狀態(tài)
	isPoolRuning_ = true;

	//記錄初始線(xiàn)程個(gè)數(shù)
	initThreadSize_ = initThreadSize;
	curThreadSize_ = initThreadSize;

	//創(chuàng)建線(xiàn)程對(duì)象
	for (int i = 0; i < initThreadSize_; i++)
	{
		auto ptr = std::make_unique<Thread>(std::bind(&ThreadPool::threadFunc, this,std::placeholders::_1));
		
		int threadId = ptr->getId();
		threads_.emplace(threadId, std::move(ptr));
	}
	 
	//啟動(dòng)所有線(xiàn)程 std::vector<Thread*> threads_;
	for (int i = 0; i < initThreadSize_; i++)
	{
		threads_[i]->start(); //需要執(zhí)行一個(gè)線(xiàn)程函數(shù)

		//記錄初始空閑線(xiàn)程的數(shù)量
		idleThreadSize_++;
	}
}
  • 設(shè)置線(xiàn)程池的運(yùn)行狀態(tài),如果線(xiàn)程在運(yùn)行狀態(tài)了,之前所有的設(shè)置相關(guān)的函數(shù)都不能運(yùn)行了,記錄初始相關(guān)數(shù)量
  • 創(chuàng)建線(xiàn)程對(duì)象,把線(xiàn)程函數(shù)threadFunc給到thread線(xiàn)程對(duì)象,使用綁定器,獲取線(xiàn)程id,方便回收線(xiàn)程資源;
  • 加入線(xiàn)程列表std::unordered_map<int, std::unique_ptr<Thread>> 類(lèi)型;
  • 啟動(dòng)所有線(xiàn)程,執(zhí)行線(xiàn)程函數(shù),threadFunc
void Thread::start()
{
	std::thread t(func_,threadId_);
	t.detach();
}

線(xiàn)程函數(shù),從任務(wù)隊(duì)列里面消費(fèi)任務(wù)

void ThreadPool::threadFunc(int threadid) //線(xiàn)程函數(shù)返回,相應(yīng)的線(xiàn)程就結(jié)束了
{
	auto lastTime = std::chrono::high_resolution_clock().now();

	for(;;)
	{
		std::shared_ptr<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;

						//通知主線(xiàn)程線(xiàn)程被回收了,再次查看是否滿(mǎn)足條件
						exitCond_.notify_all();
						return;
					}

					if (poolMode_ == PoolMode::MODE_CACHED)
					{	//超時(shí)返回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);
					}

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

						exitCond_.notify_all();
						return;
					}*/
				}
			
			idleThreadSize_--;

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

			//從任務(wù)隊(duì)列中取一個(gè)任務(wù)出來(lái)
			task = taskQue_.front();
			taskQue_.pop();
			taskSize_--;	

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

			notFull_.notify_all();

		}//釋放鎖,使其他線(xiàn)程獲取任務(wù)或者提交任務(wù)

		if (task != nullptr)
		{
			task->exec();
		}

		
		idleThreadSize_++;
		
		auto lastTime = std::chrono::high_resolution_clock().now();
	}
}
  • 獲取任務(wù)開(kāi)始的時(shí)間,便于在cached模式下,判斷是否需要回收線(xiàn)程
  • 創(chuàng)造一個(gè)Task類(lèi),獲取鎖
class Task
{
public:

	Task();
	~Task()=default;

	void exec();

	void setResult(Result*res);

	//用戶(hù)可以自定義任意任務(wù)類(lèi)型,從Task繼承,重寫(xiě)run方法,實(shí)現(xiàn)自定義任務(wù)處理
	virtual Any run() = 0;
private:
	Result* result_; //Result的生命周期》Task的
};
  • 如果此時(shí)任務(wù)隊(duì)列里沒(méi)有任務(wù),并且主函數(shù)退出了,此時(shí)會(huì)在ThreadPool析構(gòu)中設(shè)置isPoolRuning_為false,這時(shí)候就該回收線(xiàn)程資源了,并通知析構(gòu)函數(shù)是否滿(mǎn)足條件;
  • 如果isPoolRuning_為ture,但是在cached模式下,根據(jù)當(dāng)前時(shí)間和上一次線(xiàn)程使用時(shí)間,判斷有沒(méi)有超過(guò)60s,如果超過(guò)了,并且當(dāng)前線(xiàn)程數(shù)大于初始定義,說(shuō)明不需要那么多線(xiàn)程了就需要回收線(xiàn)程資源;
  • 如果不在cached模式,就阻塞等待任務(wù)隊(duì)列里面有任務(wù)
  • 獲取成功任務(wù),取出,如果隊(duì)列里面還有任務(wù),繼續(xù)通知。并且取完任務(wù),消費(fèi)了一個(gè)任務(wù) 進(jìn)行通知可以繼續(xù)提交生產(chǎn)任務(wù)了,釋放鎖,使其他線(xiàn)程獲取任務(wù)或者提交任務(wù);
  • 執(zhí)行任務(wù),把任務(wù)的返回值通過(guò)setVal方法給到Result;
  • 線(xiàn)程處理完了,更新線(xiàn)程執(zhí)行完任務(wù)調(diào)度的時(shí)間

檢查線(xiàn)程池狀態(tài)

bool ThreadPool::checkRunningState() const
{
	return isPoolRuning_;
}

執(zhí)行任務(wù)

void Task::exec()
{
	if (result_ != nullptr)
	{
		result_->setVal(run()); //多態(tài)調(diào)用,run是用戶(hù)的任務(wù)
	}
}

void Task::setResult(Result* res)
{
	result_ = res;
}

把任務(wù)的返回值通過(guò)setVal方法給到Result

信號(hào)量類(lèi)

class Semaphore
{
public:
	Semaphore(int limit = 0)
		:resLimit_(limit)
	{}

	~Semaphore() = default;

	void wait()
	{  
		std::unique_lock<std::mutex> lock(mtx_);
		//等待信號(hào)量有資源 沒(méi)有資源的話(huà) 會(huì)阻塞當(dāng)前線(xiàn)程
		cond_.wait(lock, [&]()->bool { return resLimit_ > 0; });
		resLimit_--;
	}

	void post()
	{
		std::unique_lock<std::mutex> lock(mtx_);
		resLimit_++;

		cond_.notify_all();
	}
private:

	int resLimit_;
	std::mutex mtx_;
	std::condition_variable cond_;

};

在信號(hào)量類(lèi)中使用了條件變量和互斥鎖實(shí)現(xiàn)了信號(hào)量的實(shí)現(xiàn),等待信號(hào)量資源和釋放信號(hào)量資源。

Any類(lèi)

class Any
{
public:
	Any() = default;
	~Any() = default;

	//左值
	Any(const Any&) = delete;
	Any& operator=(const Any&) = delete;

	//右值
	Any(Any&&) = default;
	Any& operator=(Any&&) = default;

	template<typename T>


	Any(T data) :base_(std::make_unique<Derive<T>>(data))
	{}


	template<typename T>
	T cast_()
	{
		Derive<T> *pd = dynamic_cast<Derive<T>*>(base_.get());
		if (pd == nullptr)
		{
			throw "type is unmatch";
		}
		return pd->data_;
	}

private:
	//基類(lèi)類(lèi)型
	class Base
	{
	public:
		virtual ~Base() = default;
	};

	//派生類(lèi)類(lèi)型
	template<typename T>//模板
	class Derive :public Base
	{
	public:
		Derive(T data) : data_(data)
		{}
		T data_; //保存了任意的其他類(lèi)型
	};

private:
	//定義一個(gè)基類(lèi)指針,基類(lèi)指針可以指向派生類(lèi)對(duì)象
	std::unique_ptr<Base> base_;
};
  • 定義了一個(gè)基類(lèi)Base
  • 定義了一個(gè)模板類(lèi)的派生類(lèi)類(lèi)型,繼承Base,其中保存了任意的其他類(lèi)型;
  • 對(duì)象包在派生類(lèi)對(duì)象里面,通過(guò)基類(lèi)指針指向派生類(lèi)對(duì)象,構(gòu)造函數(shù)可以讓Any類(lèi)型接收任意其他的數(shù)據(jù)類(lèi)型,用戶(hù)就可以使用任意期望的類(lèi)型;
  • cast_()方法把Any對(duì)象里面存儲(chǔ)的data數(shù)據(jù)提取出來(lái),基類(lèi)指針指向 派生類(lèi)指針 ,使用強(qiáng)轉(zhuǎn)dynamic_cast將基類(lèi)指針或引用轉(zhuǎn)換為派生類(lèi)指針或引用,獲取了指向的Derive對(duì)象,然后提取出來(lái)data_;

Result方法的實(shí)現(xiàn)

class Result
{
public:

	Result(std::shared_ptr<Task> task, bool isValid = true);
	~Result() = default;

	//setVal方法,獲取任務(wù)執(zhí)行完的返回值
	void setVal(Any any);

	//用戶(hù)調(diào)用get方法,獲取task的返回值
	Any get();
private:
	//存儲(chǔ)任務(wù)的返回值
	Any any_;

	//線(xiàn)程通信信號(hào)量
	Semaphore sem_;

	//指向?qū)?yīng)獲取返回值的任務(wù)對(duì)象
	std::shared_ptr<Task> task_;

	//返回值是否有效
	std::atomic_bool isValid_;
};


Result::Result(std::shared_ptr<Task> task, bool isValid)
		:isValid_(isValid)
		,task_(task)
{
	task_->setResult(this);
}

Any Result::get()
{
	if (!isValid_)
	{
		return " ";
	}

	//task任務(wù)如果沒(méi)有執(zhí)行完,這里會(huì)阻塞用戶(hù)的線(xiàn)程
	sem_.wait();
	return std::move(any_);
}

void Result::setVal(Any any)
{
	//存儲(chǔ)task的返回值
	this->any_ = std::move(any);

	//已經(jīng)獲取了任務(wù)的返回值,增加信號(hào)量資源
	sem_.post();
}
  • Result 實(shí)現(xiàn)接受提交到線(xiàn)程池的task任務(wù)執(zhí)行完成后的返回值類(lèi)型result;
  • 設(shè)置了setVal方法,獲取任務(wù)執(zhí)行完的返回值和用戶(hù)調(diào)用get方法,獲取task的返回值,使用了信號(hào)量等到setVal設(shè)置成功,才能獲取值,否則會(huì)進(jìn)入阻塞;

回到test.cpp

  • 定義了一個(gè)ThreadPool對(duì)象,默認(rèn)是固定的,可以修改為cached模式,然后開(kāi)啟線(xiàn)程(可以使用hardware_concurrency()獲取cpu核心數(shù)量);
  • 提交任務(wù)submitTask;
  • 出 } 進(jìn)行析構(gòu)

舉個(gè)栗子~

在cached模式,代碼如上test.cpp

在這里插入圖片描述

可以看到,目前四個(gè)線(xiàn)程,六個(gè)任務(wù),所以創(chuàng)建了兩個(gè)線(xiàn)程;
六個(gè)線(xiàn)程獲取任務(wù)成功,然后釋放資源成功;

固定線(xiàn)程:

int main()
{
	{
		ThreadPool pool;
		pool.start(4);

		Result res1 = pool.submitTask(std::make_shared<MyTask>(1, 1000000));
		Result res2 = pool.submitTask(std::make_shared<MyTask>(1, 1000000));
		pool.submitTask(std::make_shared<MyTask>(1, 1000000));
		pool.submitTask(std::make_shared<MyTask>(1, 1000000));
		pool.submitTask(std::make_shared<MyTask>(1, 1000000));

		ULong sum1 = res1.get().cast_<ULong>();
		std::cout << sum1 << std::endl;
	}
	
	std::cout << "main over!" << std::endl;
	getchar();
}

在這里插入圖片描述

有四個(gè)線(xiàn)程,五個(gè)任務(wù),11676線(xiàn)程獲取了兩次任務(wù),最后回收線(xiàn)程資源。

好了~基于C++11實(shí)現(xiàn)的手寫(xiě)線(xiàn)程池,就到此結(jié)束了。除此之外,在GitHub上,提供了linux下的使用方法,感興趣的小伙伴可以按照步驟實(shí)現(xiàn)一下 ~ 注意死鎖問(wèn)題!下一節(jié)會(huì)剖析基于C++17實(shí)現(xiàn)的手寫(xiě)線(xiàn)程池,代碼會(huì)看起來(lái)很輕便。

到此這篇關(guān)于基于C++11實(shí)現(xiàn)手寫(xiě)線(xiàn)程池的示例代碼的文章就介紹到這了,更多相關(guān)C++11 手寫(xiě)線(xiàn)程池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文帶你搞懂C語(yǔ)言動(dòng)態(tài)內(nèi)存管理

    一文帶你搞懂C語(yǔ)言動(dòng)態(tài)內(nèi)存管理

    動(dòng)態(tài)內(nèi)存是指在堆上分配的內(nèi)存,而靜態(tài)內(nèi)存是指在棧上分配的內(nèi)存。本文將通過(guò)幾個(gè)示例帶大家深入了解一下C語(yǔ)言的動(dòng)態(tài)內(nèi)存管理,需要的可以參考一下
    2022-11-11
  • C/C++中I/O進(jìn)階詳解及其作用介紹

    C/C++中I/O進(jìn)階詳解及其作用介紹

    這篇文章主要介紹了C/C++中I/O進(jìn)階詳解及其作用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • C語(yǔ)言中操作進(jìn)程信號(hào)的相關(guān)函數(shù)使用詳解

    C語(yǔ)言中操作進(jìn)程信號(hào)的相關(guān)函數(shù)使用詳解

    這篇文章主要介紹了C語(yǔ)言中操作進(jìn)程信號(hào)的相關(guān)函數(shù)使用詳解,分別是signal()函數(shù)和kill()函數(shù)的用法,需要的朋友可以參考下
    2015-09-09
  • iostream與iostream.h的區(qū)別詳細(xì)解析

    iostream與iostream.h的區(qū)別詳細(xì)解析

    以下是對(duì)C++中iostream與iostream.h的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下
    2013-09-09
  • C++使用jsoncpp庫(kù)解析Json

    C++使用jsoncpp庫(kù)解析Json

    對(duì)json的解析操作是我們?nèi)粘i_(kāi)發(fā)中經(jīng)常會(huì)遇到的一個(gè)需求,下面這篇文章主要給大家介紹了關(guān)于C++使用jsoncpp庫(kù)解析Json的相關(guān)資料,需要的朋友可以參考下
    2021-06-06
  • C++中遞增運(yùn)算符重載的實(shí)現(xiàn)示例

    C++中遞增運(yùn)算符重載的實(shí)現(xiàn)示例

    在C++中,遞增運(yùn)算符分為前置遞增和后置遞增,重載方式也有明顯區(qū)別,本文就來(lái)詳細(xì)的介紹一下C++中遞增運(yùn)算符重載的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2026-02-02
  • C++11中互斥鎖的使用

    C++11中互斥鎖的使用

    本文主要介紹了C++11中互斥鎖的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 詳解如何使用openssl創(chuàng)建自簽名證書(shū)

    詳解如何使用openssl創(chuàng)建自簽名證書(shū)

    這篇文章主要為大家介紹了詳解如何使用openssl創(chuàng)建自簽名證書(shū)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • 淺談QT內(nèi)存泄漏

    淺談QT內(nèi)存泄漏

    本文主要介紹了淺談QT內(nèi)存泄漏,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • C++ 遞歸遍歷文件并計(jì)算MD5的實(shí)例代碼

    C++ 遞歸遍歷文件并計(jì)算MD5的實(shí)例代碼

    在本篇文章里小編給大家整理的是一篇關(guān)于C++ 遞歸遍歷文件并計(jì)算MD5的實(shí)例代碼,有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-07-07

最新評(píng)論

康定县| 久治县| 巴林右旗| 慈溪市| 深水埗区| 图们市| 彭阳县| 鲁甸县| 二连浩特市| 中宁县| 滦平县| 九龙县| 曲松县| 简阳市| 金门县| 伊金霍洛旗| 天峨县| 彰化市| 犍为县| 南充市| 鄂托克前旗| 黑龙江省| 称多县| 枣强县| 潜山县| 岫岩| 河北省| 玉屏| 渝中区| 鹰潭市| 乳源| 辽中县| 连江县| 华安县| 普定县| 婺源县| 专栏| 定安县| 咸宁市| 南丰县| 斗六市|