IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++11 线程池实现 -> 正文阅读

[C++知识库]C++11 线程池实现

概述

1、一个线程 pool,所有线程阻塞等待唤醒(有任务时唤醒)
2、任务队列 queue,队列中添加任务后就唤醒线程,线程从队头取走任务执行,典型的生产者-消费者模型。
3、mutex对队列上锁, 保证队列任务添加和取走的同步性
4、当线程数不足时可以动态增加线程数量。

代码

threadpool.hpp头文件

#pragma once
#include <iostream>
#include<stdlib.h>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<vector>
#include<functional>
#include<queue>
#include<atomic>
#define N 10    //默认初始化线程数量
#define THREADPOOL_MAX_NUM  500   //最大线程数量
using namespace std;
class ThreadPool {

public:
	//自定义void()的函数类型
	using Task = function<void()>;

	size_t initnum;
	//线程数组
	vector<thread> _pool;

	//任务队列
	queue<Task> _tasks;

	//互斥锁条件变量
	mutex _mutex;
	condition_variable _cond;

	//线程池是否在工作
	atomic<bool> _run;
	//空闲线程数量
	atomic<int>  _idlThreadNum;
public:
	ThreadPool(int cnt = N) :_run(true), _idlThreadNum(cnt)
	{
		addThread(cnt);  //初始化线程池,线程池数量为cnt
	}
	~ThreadPool()
	{
		_run = false;
		_cond.notify_all(); // 唤醒所有线程执行
		for (thread& thrd : _pool) {
			//thread.detach(); // 让线程“自生自灭”
			if (thrd.joinable())    //线程还在执行任务中则等待
				thrd.join(); // 等待任务结束, 前提:线程一定会执行完			
		}
	}

public:
	//向任务队列添加任务
	void addTask(const Task& f)
	{
		if (_run) {
			//保护共享资源    
			unique_lock<mutex>lk(_mutex);

			//给队列中添加任务
			_tasks.push(f);
			cout << "---------Add a task---------" << endl;
			//空闲线程不够时,增加线程
			if (_idlThreadNum < 1 && _pool.size() < THREADPOOL_MAX_NUM)
			{
				addThread(1);
				cout << "new thread" << endl;
			}

			//唤醒等待线程
			_cond.notify_one();
		}
	}
	//向线程池中增加线程
	void addThread(int num)
	{
		for (; num > 0 && _pool.size() < THREADPOOL_MAX_NUM; num--) {
			_pool.push_back(thread(&ThreadPool::runTask, this));
		}
	}
	void runTask()
	{
		//不断遍历队列,判断要是有任务的话,就执行
		while (_run) {

			Task task; // 获取一个待执行的 task
			{
				// unique_lock 相比 lock_guard 的好处是:可以随时 unlock() 和 lock()
				unique_lock<mutex> lock(_mutex);
				_cond.wait(lock, [this] {
					return !_run || !_tasks.empty();   //会暂时解锁lock并等待唤醒
					}); // wait 直到有 task
				if (!_run && _tasks.empty())
					return;
				task = move(_tasks.front()); // 按先进先出从队列取一个 task
				_tasks.pop();
			}
			_idlThreadNum--;
			task();//执行任务
			_idlThreadNum++;
		}
	}
};

测试程序

#include<iostream>
#include"threadpool.hpp"
using namespace std;


void func(int i) {
	cout << "pthread_id=" << this_thread::get_id() << endl;
	cout << "task id" << "------>" << i << endl;
	this_thread::sleep_for(chrono::seconds(rand() % 5));    //模拟工作时长
}
int main()
{
	srand(time(nullptr));
	ThreadPool p(5);
	int i = 0;
	int num = 20;
	while (num--) {
		i++;
		//调整线程之间cpu调度
		this_thread::sleep_for(chrono::milliseconds(100));
		auto task = bind(func, i);
		p.addTask(task);
	}
	return 0;
}

测试结果:
在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 07:31:54  更:2021-07-28 07:34:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/29 4:47:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码