实现一个简单的C++线程池

C++线程池的优势与劣势

C++线程池是指在程序中预先创建一组线程,然后在需要执行任务时,将任务分配给这些线程执行。线程池具有以下优势:

  1. 减少创建和销毁线程的开销:创建和销毁线程是需要消耗系统资源的,而线程池中的线程是预先创建好的,可以重复利用,因此可以减少这些开销。
  2. 提高程序的响应速度:当程序需要执行任务时,可以直接从线程池中获取一个空闲线程执行任务,无3. 需等待线程创建的时间,因此可以提高程序的响应速度。
    减少线程切换的开销:线程池中的线程数量通常是有限的,因此可以减少线程切换的开销。

然而,线程池也存在以下劣势:

  1. 线程数量限制:线程池中的线程数量是有限的,因此无法处理无限量的任务。如果任务数量超过线程池的大小,程序可能会出现响应慢或者崩溃的情况。
  2. 任务分配不均:线程池中的线程是预先创建好的,因此可能会出现某些线程执行任务过于频繁,而其他线程则空闲的情况。这可能会导致任务分配不均,影响程序的性能。
  3. 线程同步问题:线程池中的线程是共享内存空间的,因此需要使用同步机制来避免数据竞争和死锁等问题。这会增加程序的复杂性和调试难度。

综上所述,使用线程池可以提高程序的性能和响应速度,但需要注意线程数量限制、任务分配不均和线程同步问题等问题。

以下是C++实现了一个简单的线程池

#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>// 定义任务类型,可以是任何可调用对象
using Task = std::function<void()>;// 线程池类
class ThreadPool {
public:// 构造函数,创建指定数量的线程ThreadPool(size_t threadCount) {for (size_t i = 0; i < threadCount; ++i) {threads.emplace_back(&ThreadPool::threadFunc, this);}}// 析构函数,等待所有线程结束并释放资源~ThreadPool() {terminate = true; // 设置终止标志condition.notify_all(); // 唤醒所有等待中的线程for (auto& t : threads) {if (t.joinable()) {t.join(); // 等待线程结束}}}// 向任务队列中添加任务void addTask(const Task& task) {{std::lock_guard<std::mutex> lock(queueMutex); // 对任务队列加锁taskQueue.emplace(task); // 将任务加入队列}condition.notify_one(); // 唤醒一个等待中的线程}private:// 线程执行函数,循环获取并执行任务void threadFunc() {while (true) {Task task;{std::unique_lock<std::mutex> lock(queueMutex); // 对任务队列加锁condition.wait(lock, [this]() { return !taskQueue.empty() || terminate; }); // 等待任务或终止信号if (terminate && taskQueue.empty()) {break; // 如果收到终止信号且任务队列为空,则退出循环}task = taskQueue.front(); // 取出队首任务taskQueue.pop(); // 弹出队首任务}task(); // 执行任务}}std::vector<std::thread> threads; // 线程集合std::queue<Task> taskQueue; // 任务队列std::mutex queueMutex; // 任务队列互斥锁std::condition_variable condition; // 条件变量,用于同步线程和任务队列bool terminate = false; // 终止标志,用于通知线程结束
};// 测试函数,打印一句话和当前线程ID
void printHello(int i) {std::cout << "Hello, I am task " << i << ", running on thread " << std::this_thread::get_id() << "\n";
}int main() {ThreadPool pool(4); // 创建一个包含4个线程的线程池for (int i = 0; i < 10; ++i) {pool.addTask(std::bind(printHello, i)); // 向线程池中添加10个任务}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/52066.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java进阶篇--IO流的第二篇《多样的流》

目录 Java缓冲流 BufferedReader和BufferedWriter类 Java随机流 Java数组流 字节数组流 ByteArrayInputStream流的构造方法&#xff1a; ByteArrayOutputStream流的构造方法&#xff1a; 字符数组流 Java数据流 Java对象流 Java序列化与对象克隆 扩展小知识&#x…

【附安装包】CIMCO Edit 8安装教程|数控编程必备

软件下载 软件&#xff1a;CIMCO Edit版本&#xff1a;8语言&#xff1a;简体中文大小&#xff1a;249.18M安装环境&#xff1a;Win11/Win10/Win8/Win7硬件要求&#xff1a;CPU2.0GHz 内存4G(或更高&#xff09;下载通道①百度网盘丨64位下载链接&#xff1a;https://pan.baid…

学习JAVA打卡第四十一天

字符串与字符数组、字节数组 ⑴字符串与字符数组 String类的构造方法String&#xff08;char a[]&#xff09;和String&#xff08;char a[]&#xff09;,int offset,int length,分别用数组a中的全部字符和部分字符创建string对象。 String类也提供将string对象的字符序列存…

Docker常见配置实验

1、使用mysql:5.6和 owncloud 镜像&#xff0c;构建一个个人网盘。 1、拉取mysql5.6与owncloud的镜像 docker pull mysql:5.6 docker pull mysql:5.6 2、生成容器实例&#xff0c;构建个人网盘 docker run -d --name mydb1 --env MYSQL_ROOT_PASSWORD123456 mysql:5.6 docker …

关于Java中@Transient主键的作用的一些介绍

Transient主下面是关于Transient主键的使用方法、代码案例以及与transient关键字的区别&#xff0c;以及一些实用场景的详细介绍。 1. Transient主键的作用 在实体类中&#xff0c;通常需要将某些字段标记为主键&#xff0c;并将其映射到数据库中的主键字段。但是&#xff0c…

mybatisplus查询报Invalid bound statement (not found)

问题描述 在复现一个老项目时&#xff0c;使用了mybatisplus&#xff0c;其版本为3.1.1。 结果项目启动成功&#xff0c;但是在使用mapper查询时&#xff0c;报了如下错误&#xff1a;Invalid bound statement (not found) 项目的mapper的xml文件是放在resources/mapper目录下…

mac清理磁盘空间软件有哪些 mac清理磁盘空间怎么清理

随着时间的推移&#xff0c;Mac电脑上的文件会越来越多&#xff0c;很快就会占满磁盘空间。这时候&#xff0c;我们需要一个好的Mac清理磁盘空间软件来释放空间&#xff0c;保持电脑的良好性能。那么&#xff0c;mac清理磁盘空间软件有哪些呢&#xff1f;接下来&#xff0c;我将…

如何维护自己的电脑的措施

维护自己的电脑可以采取以下措施&#xff1a; 硬件维护&#xff1a;定期清理电脑表面的灰尘和污垢&#xff0c;避免灰尘对电脑内部部件造成影响。电源插座要保持接触良好&#xff0c;保证电脑的电源稳定。如果使用笔记本电脑&#xff0c;要注意保证散热通畅&#xff0c;避免电…

设计模式(单例模式,工厂模式),线程池

目录 什么是设计模式? 单例模式 饿汉模式 懒汉模式 工厂模式 线程池 线程池种类 ThreadPoolExcutor的构造方法: 手动实现一个线程池 什么是设计模式? 计算机行业程序员水平层次不齐,为了让所有人都能够写出规范的代码,于是就有了设计模式,针对一些典型的场景,给出一…

java+springboot+mysql村务档案管理系统

项目介绍&#xff1a; 使用javaspringbootmysql开发的村务档案管理系统&#xff0c;系统包含超级管理员、工作人员角色&#xff0c;功能如下&#xff1a; 超级管理员&#xff1a;系统用户管理&#xff08;工作人员管理&#xff09;&#xff1b;公开资料&#xff1b;会议记录&…

A Survey on Knowledge-Enhanced Pre-trained Language Models

摘要 自然语言处理(NLP)已经通过使用BERT等预训练语言模型(plm)发生了革命性的变化。尽管几乎在每个NLP任务中都创造了新的记录,但plm仍然面临许多挑战,包括可解释性差,推理能力弱,以及在应用于下游任务时需要大量昂贵的注释数据。通过将外部知识集成到plm中,知识增强预训…

.NET 最便捷的Log4Net日志记录器

最便捷的Log4Net使用方法 LOG4NET 配置日志记录器开始引用nuget LOG4NET 配置日志记录器 Apache log4net 库是一个帮助程序员将日志语句输出到各种的工具 的输出目标。log4net是优秀的Apachelog4j™框架的移植 Microsoft.NET 运行时。我们保持了与原始log4j相似的框架 同时利…

Rust处理JSON

基本操作 Cargo.toml: [package]name "json"version "0.1.0"edition "2021"# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html[dependencies]serde { version "1", features …

前端(十四)——DOM节点操作手册:你需要了解的一切

&#x1f642;博主&#xff1a;小猫娃来啦 &#x1f642;文章核心&#xff1a;DOM节点操作手册&#xff1a;你需要了解的一切 文章目录 前言DOM基础知识操作现有节点创建新节点遍历节点树修改节点属性和样式事件处理实践应用动态创建表格动态更新列表 前言 DOM&#xff08;文档…

算法岗和开发岗有什么区别?

算法岗和开发岗有什么区别&#xff1f; ​ 算法岗位和开发岗位在实际应用中有很大的差异&#xff0c;而且其工作的内容重心也不一样。企业对职位能力的要求也是存在着很大的区别。 ​ 其实在真正的实践中&#xff0c;只有大厂才对这两个岗位分的比较清楚&#xff0c;小的公司…

计算机网络第3章(数据链路层)

计算机网络第3章&#xff08;数据链路层&#xff09; 3.1 数据链路层概述3.1.1 概述3.1.2 数据链路层使用的信道3.1.3 三个重要问题 3.2 封装成帧3.2.1 介绍3.2.2 透明传输3.2.3 总结 3.3 差错检测3.3.1 介绍3.3.2 奇偶校验3.3.3 循环冗余校验CRC(Cyclic Redundancy Check)3.3.…

【FAQ】安防监控视频汇聚平台EasyCVR接入GB国标设备,无法显示通道信息的排查方法

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

【分析绘图】R语言实现一些常见的绘图

微生信-在线绘图网站 线性图 library(ggplot2)x <- rnorm(100, 14, 5) # rnorm(n, mean 0, sd 1) y <- x rnorm(100, 0, 1) ggplot(data NULL, aes(x x, y y)) # 开始绘图geom_point(color "darkred") # 添加点annotate("text",x 13,…

【从零学习python 】92.使用Python的requests库发送HTTP请求和处理响应

文章目录 URL参数传递方式一&#xff1a;使用字典传递参数URL参数传递方式二&#xff1a;直接在URL中拼接参数获取响应头信息获取响应体数据a. 获取二进制数据b. 获取字符数据c. 获取JSON数据 进阶案例 URL参数传递方式一&#xff1a;使用字典传递参数 url https://www.apiop…

idea使用tomcat

1. 建立javaweb项目 2. /WEB-INF/web.xml项目配置文件 如果javaweb项目 先建立项目&#xff0c;然后在项目上添加框架支持&#xff0c;选择javaee 3. 项目结构 4.执行测试&#xff1a;