当前位置: 首页 > news >正文

C++(27): 线程池

目录

1. 概述

2. 例程

(1)ThreadPool.h

(2)ThreadPool.cpp

(3)Start.cpp

(4)编译


1. 概述

线程池技术绝不是C++独有的,Java和Python都有比较晚完善的线程池构造接口。

通俗的讲,线程池只是一种管理线程的方式。很多时候,我们为了充分利用CPU和Memory资源,会创建一些独立的线程,执行同步或异步的任务。但有一个不得不考虑的问题是,现成的创建和销毁本身也是消耗系统资源的,尤其是一些需要频繁创建和销毁线程的应用场景下。当然有时候有一些连续的任务也不需要通过线程池技术来完成。

如上所述,为了避免频繁创建和销毁线程带来的系统资源的消耗,我们可以提前创建一定数量的线程,用来等待和处理队列中的事务,无需反复地创建和销毁线程。

2. 例程

(1)ThreadPool.h

#ifndef __THREADPOOL_H__#define __THREADPOOL_H__#include <iostream>  #include <vector>  #include <queue>  #include <thread>  #include <mutex>  #include <condition_variable>  #include <future>#include <functional>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <stdint.h>class ThreadPool{public:  ThreadPool(size_t threads);template<class F, class... Args>  auto enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type>{using return_type = typename std::result_of<F(Args...)>::type;  auto task = std::make_shared<std::packaged_task<return_type()>>(  std::bind(std::forward<F>(f), std::forward<Args>(args)...)  );  std::future<return_type> res = task->get_future();  {  std::unique_lock<std::mutex> lock(queueMutex);  if (stop) {  throw std::runtime_error("enqueue on stopped ThreadPool");  }  tasks.emplace([task]() { (*task)(); });  }  condition.notify_one();  return res;  }~ThreadPool();private:  std::vector<std::thread> workers;  std::queue<std::function<void()>> tasks;  std::mutex queueMutex;  std::condition_variable condition;  bool stop;  };#endif ///< __THREADPOOL_H__

(2)ThreadPool.cpp

#include "ThreadPool.h"ThreadPool::ThreadPool(size_t threads) : stop(false){for (size_t i = 0; i < threads; ++i) {  workers.emplace_back([this] {  while (true) {  std::function<void()> task;  {  std::unique_lock<std::mutex> lock(this->queueMutex);  this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });  if (this->stop && this->tasks.empty()) {  return;  }  task = std::move(this->tasks.front());  this->tasks.pop();  }  task();  }  });  }  }ThreadPool::~ThreadPool(){  {  std::unique_lock<std::mutex> lock(queueMutex);  stop = true;  }  condition.notify_all();  for (std::thread &worker : workers) {  worker.join();  }  }  

(3)Start.cpp

#include <iostream>  #include <vector>  #include <queue>  #include <thread>  #include <mutex>  #include <condition_variable>  #include <future>#include <functional>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <stdint.h>#include "ThreadPool.h"/** sudo g++ -std=c++17 -o ./Start.bin ./*.cpp -lpthread */#define EXTERNAL_FUNC 0 ///< 0: 类内部成员///< 1: 类外部成员#if EXTERNAL_FUNC == 1// 定义一个返回整数的函数  int intFunction(int x){return x * x;}  // 定义一个返回字符串的函数  std::string stringFunction(std::string s){return s + " world";}int main(int argc, char* argv[]){ThreadPool pool(4);  // 使用enqueue来执行intFunction,传入参数4  auto result1 = pool.enqueue(intFunction, 4);  // 使用enqueue来执行stringFunction,传入参数"hello"  auto result2 = pool.enqueue(stringFunction, "hello");  // 获取并打印结果  std::cout << "result1: " << result1.get() << std::endl;  // 应该打印出16  std::cout << "result2: " << result2.get() << std::endl;  // 应该打印出"hello world"  return 0;  }#else ///< 作为类成员class DemoClass{public:  DemoClass(int num_threads = 1){if(num_threads <= 0 ){num_threads = 1;}pool = new ThreadPool(num_threads);}~DemoClass(){delete pool;pool = nullptr;}void printTask(int n){  std::cout << "Processing " << n << std::endl;}  void startProcessing(){for (int i = 1; i <= 50; ++i){pool->enqueue(&DemoClass::printTask, this, i);usleep(1); ///< 短暂的等待是有必要的.}  }private:ThreadPool* pool = nullptr;};  int main(int argc, char* argv[]){DemoClass myClass(10);  myClass.startProcessing();  return 0;  }#endif

(4)编译

sudo g++ -std=c++17 -o ./Start.bin ./*.cpp -lpthread

相关文章:

C++(27): 线程池

目录 1. 概述 2. 例程 &#xff08;1&#xff09;ThreadPool.h &#xff08;2&#xff09;ThreadPool.cpp &#xff08;3&#xff09;Start.cpp &#xff08;4&#xff09;编译 1. 概述 线程池技术绝不是C独有的&#xff0c;Java和Python都有比较晚完善的线程池构造接口…...

每日一题-贪心算法

122. 买卖股票的最佳时机 II - 力扣&#xff08;LeetCode&#xff09; 55. 跳跃游戏 - 力扣&#xff08;LeetCode&#xff09; 这个题目一开始肯定是会懵&#xff0c;就比如说一开始先跳几步&#xff0c;之后再怎么跳&#xff0c;其实我们就可以用最大范围来算就行了&#xff0…...

PSO 算法实例(手动推导过程)

PSO 算法实例 引言正文PSO 算法步骤PSO 实例步骤1 定义目标函数步骤2 初始化每个粒子的位置和速度步骤3 使用目标函数进行评估步骤4 更新单个粒子的最佳位置(局部最优值)步骤5 更新全局最佳位置(全局最优值)步骤6 更新每个粒子的位置和速度步骤7 使用目标函数评估新的位置步…...

解决antd TreeSelect 返回值不包含父节点问题 -自定义组件(react)

在写一个表单时使用了antd的 TreeSelect&#xff0c;在对TreeSelect的值提交时发现&#xff0c;父节点的值在半选状态时未提交&#xff0c;在选中状态时&#xff08;子节点全选&#xff09;&#xff0c;子节点不提交&#xff0c;只提交父节点&#xff0c;这与后端需求不符&…...

花四小时,写了个在线实时绘制等值面图小软件,明晚上线,喜欢的小伙伴关注哦

科研党的福音&#xff0c;绘图再也不需要安装一堆软件了&#xff0c;可以在线绘图了&#xff1b; 只需要传入绘制的区间、色值、以及所需要绘制的数据就可以直接出图了&#xff0c;可绘制各种等值面图&#xff0c;比如降水分布&#xff0c;高温分布&#xff0c;人口分布&#x…...

c++的vector用法

文章目录 1. 创建和初始化 std::vector2. 添加和删除元素3. 访问和遍历元素4. std::vector 的其他常用操作 std::vector 是 C 标准库中的一个动态数组容器&#xff0c;提供了灵活的存储和访问功能。 1. 创建和初始化 std::vector #include <iostream> #include <vect…...

【Linux网络】Linux网络初探:开启网络世界的大门

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; 前言&#xff1a;我们已经系统的学习了Linux的基本操作、进程、线程、文件、通信等待&#xff0c;但是在如今社会没有网络通信方式是万万不行的&#xff0c;今天我们就走进网络中&#xff0c;系统的学习一下有关Linux网…...

目录、用户与组、出错相关函数、时间函数

一、目录相关函数及属性 1、 opendir()函数 opendir 用于打开一个目录&#xff0c;并返回一个目录流指针。name&#xff1a;要打开的目录的路径。 返回值&#xff1a;成功时返回指向目录流的指针&#xff0c;失败时返回 NULL。 #include <dirent.h> DIR *opendir(con…...

<keep-alive> 一分钟了解

<keep-alive> 一分钟了解 <keep-alive> 是 Vue.js 提供的一个抽象组件&#xff0c;它的主要用途是在页面或组件切换时保留其状态&#xff0c;避免重复执行昂贵的渲染操作&#xff0c;从而提升应用性能。 文章目录 <keep-alive> 一分钟了解 一、 <keep-ali…...

Android 启动动画太生硬

跟 android:launchMode"singleTask"属性无关系 请禁用路由 ARouter.getInstance() .build(Routes.Main.MAIN) .withTransition(R.anim.activity_anim_in, R.anim.activity_anim_out).navigation() 正确做法是 val intent Intent(thisSplashActivity,MainActivit…...

深度学习中常用概念总结

最近在做深度学习&#xff0c;里面涉及到很多概念&#xff0c;有的名称都差不多容易记混。所以写这篇文章总结一下。眼过千遍不如手过一遍。 1. 轮数&#xff08;Epochs&#xff09;: 一轮&#xff08;Epoch&#xff09;指的是整个训练数据集在训练过程中被完整使用一次。…...

进 程

1.进程&#xff1a;进行中的程序。 微观串行&#xff0c;宏观并行。 程序的一次执行过程 进程是程序的一个实例 一个程序可以对应一个或多个进程。 2.为什么需要进程&#xff1f; 3.进程的组成部分&#xff1a; 进程 pcb 块 栈|堆|bss|data|text 其中&#xff1a; 家族…...

Taro-UI

一、安装Taro UI 进入项目文件&#xff0c;执行项目 //使用yarn安装taro-ui yarn add taro-ui//使用npm安装taro-ui npm install taro-ui//注&#xff1a;因为要支持自定义主题功能&#xff0c;需要将样式从组件中抽离出来&#xff0c;在微信小程序中依赖 globalClass 功能&a…...

TypeScript 之 JavaScript文件类型检查

启用对 JavaScript 文件的类型检查 在 TypeScript 编译选项 compilerOptions 全部配置项 中&#xff0c;可以通过以下2个属性配置 JavaScript Support&#xff1a; allowJs 是否允许编译 JavaScript 文件。默认值是 false。在默认情况下&#xff0c;TypeScript 编译器只处理 .…...

基本数据类型变量间的自动提升与强制转换以及进制的转换

基本数据类型变量间的自动提升与强制转换 测试基本数据类型的运算规则 这里基本类型不包括布尔 运算规则 自动类型提升 当容量小的变量与容量大的变量做运算时&#xff0c;结果自动转换容量大的数据类型 说明&#xff1a;此时容量大小&#xff0c;指的是数据范围大小&…...

SparseConv 的学习笔记

安装 环境设置在74.183 sdfstudio 里面,SparseNeus 推荐的版本是是 torchsparse 2.0.0版本 命令行如下&#xff1a; 需要 C 的 sudo 权限指定安装&#xff1a; ## 安装依赖项 conda install -c conda-forge sparsehash sudo apt-get install libsparsehash-dev 进入官网下…...

vscode 快速生成vue 格式

1.用快捷Ctrl Shift P唤出控制台 输入“Snippets”并选择 Snippets: Configure User Snippets 2.输入vue&#xff0c;选中vue.json vs code自动生成vue.json文件 3.在 vue.json 中添加模板 {"Print to console": {"prefix": "vue2","b…...

react笔记:redux

redux状态管理 安装redux&#xff1a;num i redux 新建redux文件夹&#xff1a; store.jscount_reducer.js count_action.js constant.js (常量&#xff09; 1. store.js文件&#xff1a; // 该文件专门用于暴露一个store对象&#xff0c;整个应用只有一个store对…...

数据结构与算法--图的应用

文章目录 回顾提要连通图生成树最小生成树构造最小生成树的算法普里姆(Prim)算法克鲁斯卡尔(Kruskal)算法 最短路径狄杰斯特拉 (Dijkstra) 算法当前最短路径的更新拓扑排序拓扑排序方法拓扑排序示例总结 回顾 图的遍历方法&#xff1a; 深度优先遍历 (DFS)&#xff1a;从任意…...

【leetcode图文详解】特殊数组II : 空间换时间的“记忆化”,越多越好吗?

题目详解 需求&#xff1a;判断给定区间内的元素是否满足“特殊数组”要求 尝试: 暴力求解? 如果试着直接对每个queries中的区间进行检测而不做其他处理&#xff0c;那么最后不出意外地超时了。。 细想优化策略&#xff0c;不难察觉到其中可能存在大量的重复运算 那还等什…...

离线安装prometheus与Grafana实现可视化监控

简介 prometheus 是一个专为云环境设计的开源系统监控和警报工具&#xff0c;它收集并存储多维度的时间序列数据&#xff0c;通过PromQL查询语言提供强大的数据检索能力&#xff0c;并支持可视化及警报功能。而 Grafana 则是一个开源的数据可视化平台&#xff0c;能够与包括Pr…...

【Python学习-UI界面】PyQt5 小部件7-QSpinBox 计数器

样式如下: 一个 QSpinBox 对象向用户呈现一个文本框&#xff0c;右侧有一个上下按钮&#xff0c;显示一个整数。如果按下上下按钮&#xff0c;文本框中的值将增加/减少。 默认情况下&#xff0c;框中的整数从0开始&#xff0c;最高到99&#xff0c;并以步长1变化。对于浮点数…...

[二次元]个人主页搭建

文章目录 域名买一个免费的 框架HexoHexo-Theme-ParticleX Halo 参考 域名 买一个 有钱人玩这个 免费的 github.io 教程在github官方文档有&#xff1b; 框架 Hexo 静态的 Hexo-Theme-ParticleX Argvchsの小窝 Halo 动态的 halo 参考 基于Hexo框架的GitHub个人主页…...

Spring Data JPA 自动创建时间的相关注解和用法

以Springboot项目为例 在实体类上加上注解 EntityListeners(AuditingEntityListener.class)在相应的字段上添加对应的时间注解 LastModifiedDate 和 CreatedDateApplication启动类中添加注解 EnableJpaAuditing...

Java基础之隐式类型转换

类型转换 基本数据类型表示范围大小排序&#xff1a; 在变量赋值及算术运算的过程中&#xff0c;经常会用到数据类型转换&#xff0c;其分为两类&#xff1a; 隐式类型转换 显式类型转换 1 隐式类型转换 情形1&#xff1a;赋值过程中&#xff0c;小数据类型值或变量可以直…...

【数据结构与算法 | 图篇】Dijkstra算法(单源最短路径算法)

1. 前言 由图&#xff1a; 如果我们想要求得节点1到节点5&#xff08;也可以是其他节点&#xff09;的最短路径&#xff0c;我们可以使用Dijkstra算法。 2. 步骤与思路 1. 将所有顶点标记为未访问(顶点类的visited属性设置为false)。创建一个未访问顶点的集合。 2. 为每个顶…...

windows c转linux c要做的事情。

写在开头&#xff1a; 最近的copy项目要转到windows版本了&#xff0c;一直在跟进做这个事情。 直入主题说下移植过程中可能涉及以下几个方面的调整&#xff1a;‌ 编译器和工具链的更改&#xff1a;‌Windows和Linux使用不同的编译器和工具链&#xff0c;‌因此需要在Windo…...

【高等代数笔记】002.高等代数研究对象(二)

1. 高等代数的研究对象 1.4 一元高次方程的求根 a n x n a n − 1 x n − 1 . . . a 1 x a 0 0 a_{n}x^{n}a_{n-1}x^{n-1}...a_{1}xa_{0}0 an​xnan−1​xn−1...a1​xa0​0 等式左边是一元多项式。 所有一元多项式组成的集合称为一元多项式环。...

ubuntu服务器部署的mysql本地连不上的问题

试过了网上的所有方法,都连不上,可以执行: SELECT user, host, plugin FROM mysql.user WHERE user root; 查一下:plungin这个连接插件是不是auth_socket, auth_socket是只能本地连接的插件,需要修改: ALTER USER root% IDENTIFIED WITH mysql_native_password BY your_pass…...

python redis安装

python redis安装 #方法1、 sudo apt-get install redis-server python 支持包&#xff1a; (其实就一个文件&#xff0c;搞过来就能用) sudo apt-get install python-redis #方法2、 sudo pip install redis...