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

C++并发编程之五 高级线程管理

文章目录

    • 5.1.1 线程池

5.1.1 线程池

在前面我们引入了线程的通信和同步手段,那么为什么还要引入线程池呢?
线程池是一种管理多个线程的技术,它可以减少线程的创建和销毁的开销,提高并发性能。线程池中有一定数量的空闲线程,当有新的任务到来时,就从池中分配一个线程来执行任务,当任务完成后,线程返回池中等待下一个任务。这样可以避免频繁地创建和销毁线程,节省资源和时间。

用C++11实现线程池的基本思路是:

  1. 创建一个任务队列,用来存放用户提交的任务。
  2. 创建一个线程队列,用来存放一定数量的空闲线程。
  3. 使用互斥锁和条件变量来同步任务队列和线程队列的访问。
  4. 当有新的任务到来时,将任务放入任务队列,并通知一个空闲线程去执行它。
  5. 当一个线程完成了任务后,将自己放回线程队列,并等待下一个任务。
  6. 当用户想要停止线程池时,向所有线程发送停止信号,并等待它们结束。

下面是一个简单的示例代码:

#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>class ThreadPool {
public:// 构造函数,创建指定数量的线程ThreadPool(size_t num_threads) : stop(false) {for (size_t i = 0; i < num_threads; ++i) {workers.emplace_back([this]() {while (true) {std::function<void()> task;// 从任务队列中取出一个任务{std::unique_lock<std::mutex> lock(this->queue_mutex);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();}});}}// 向任务队列中添加一个新的任务template<class F, class... Args>void enqueue(F&& f, Args&&... args) {std::function<void()> task = std::bind(std::forward<F>(f), std::forward<Args>(args)...); {std::unique_lock<std::mutex> lock(queue_mutex);tasks.emplace(task);}condition.notify_one();}// 停止所有线程并回收资源~ThreadPool() {{std::unique_lock<std::mutex> lock(queue_mutex);stop = true;}condition.notify_all();for (std::thread& worker : workers) worker.join();}private:std::vector<std::thread> workers; // 线程队列std::queue<std::function<void()>> tasks; // 任务队列std::mutex queue_mutex; // 互斥锁std::condition_variable condition; // 条件变量bool stop; // 停止标志
};// 测试函数,打印一些信息
void print(int i) {std::cout << "Hello from thread " << i << "\n";
}int main() {ThreadPool pool(4); // 创建4个线程的线程池for (int i = 0; i < 10; ++i) pool.enqueue(print, i); // 添加10个测试任务}
  1. bar(std::forward<Args>(args)…) 中的 … 是函数参数包展开语法,它会将 args中的每个参数展开成一个单独的函数参数。这意味着,如果 args是一个包含多个参数的参数包,那么这个展开语法将会在函数调用时展开成多个函数参数。
  2. 例如,假设 args 包含两个参数,一个 int 和一个 double,那么bar(std::forward(args)…) 将会被展开成 bar(std::forward(arg1), std::forward(arg2)),其中 arg1 和 arg2 分别代表参数包中的第一个参数和第二个参数。
  3. 因此,使用函数参数包展开语法可以将参数包中的参数展开成多个单独的函数参数,从而使得参数可以被正确地转发给其他函数或进行其他操作。
  4. 在展开语法中,…符号前面的内容是函数模板中的参数包名称(例如:T),而…符号本身是展开语法符号,用于告诉编译器要将参数包展开成一系列参数,并将它们传递给函数func。
  5. 在这个例子中,逗号操作符不是必需的,因为参数包展开符号已经足够明确地告诉编译器要将参数包展开成一系列参数。

相关文章:

C++并发编程之五 高级线程管理

文章目录5.1.1 线程池5.1.1 线程池 在前面我们引入了线程的通信和同步手段&#xff0c;那么为什么还要引入线程池呢&#xff1f; 线程池是一种管理多个线程的技术&#xff0c;它可以减少线程的创建和销毁的开销&#xff0c;提高并发性能。线程池中有一定数量的空闲线程&#x…...

单片机——IIC协议与24C02

1、基础知识 1.1、IIC串行总线的组成及工作原理 I2C总线只有两根双向信号线。一根是数据线SDA&#xff0c;另一根是时钟线SCL。 1.2、I2C总线的数据传输 I2C总线进行数据传送时&#xff0c;时钟信号为高电平期间&#xff0c;数据线上的数据必须保持稳定&#xff0c;只有在时钟…...

案例05-将不必要的逻辑放到前端(发送调查问卷)

目录一&#xff1a;背景介绍背景二&#xff1a;思路&方案重大问题&#xff1a;解决办法优点&#xff1a;三&#xff1a;总结一&#xff1a;背景介绍 本篇博客书写的意义是警示大家不必把不必要的逻辑放到前端。 明确前后端分离的意义。 背景 下面的主要逻辑是&#xff1…...

【每日一题】——矩阵相等判定

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;每日一题 &#x1f48c;其他专栏&#xff1a; &#x1f534; 每日反刍 &#x1f7e2; 读书笔记 &#x1f7e1; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0c;缓称…...

Linux防火墙的关闭

查看防火墙的状态打开终端输入如下命令systemctl status firewalld如图所示&#xff1a;running表示防火墙目前处于打开状态输入命令进行关闭防火墙&#xff1a;systemctl stop firewalld如图所示正常的用户是没有权限的&#xff0c;需要输入管理员的密码才能够进行关闭防火墙。…...

Request和Response的概述

⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;输出优质文章⭐作者主页&#xff1a;︶ㄣ释然⭐如果觉得文章写的不错&#xff0c;欢迎点个关注&#x1f609;有写的不好的地方也欢迎指正&#xff0c;一同进步&#x1f601;Request和Respo…...

常见的Web安全漏洞:SYN攻击/CSRF/XSS

一、SYN攻击&#xff08;属于DOS攻击&#xff09; 什么情况下被动方出现SYN_RCVD状态?(flood攻击服务) 客户伪造 ip 端口&#xff0c; 向服务端发送SYN请求。完成2次握手&#xff0c;第三次服务端 等待客户端ACK确认&#xff0c;但由于客户不存在服务端一直未收到确认&#…...

【STC15单片机】 超声波模块的使用

目录 1 基于STC15F2K60S2的超声波测距代码 1.1 基本注意事项 1.1.1 跳线帽接法 1.1.2 晶振设置 1.2 板载超声波工作原理 1.2.1 原理总结 1.2.2 超声波代码思路 1.3 STC15单片机代码部分 1.3.1 定时器0&定时器1初始化 1.3.2 超声波ultrasonic.c ultrasonic.h文件配…...

SpringBoot 动态操作定时任务(启动、停止、修改执行周期)增强版

前段时间编写了一篇博客SpringBoot 动态操作定时任务&#xff08;启动、停止、修改执行周期&#xff0c;该篇博客还是帮助了很多同学。 但是该篇博客中的方法有些不足的地方&#xff1a; 只能通过前端控制器controller手动注册任务。【具体的应该是我们提前配置好我们的任务&am…...

快排函数 -- qsort函数(Quick Sort)

文章目录&#x1f50e;1.qsort函数简介&#x1f4a1;1.1.函数原型&#x1f4a1;1.2.参数含义&#x1f50e;2.比较函数介绍&#x1f50e;3.比较函数使用案例&#x1f4a1;3.1.整型数组&#x1f4a1;3.2.浮点型数组&#x1f4a1;3.3.结构体类型 - 字符串&#x1f50e;4.利用冒泡排…...

条形码和二维码

前言&#xff1a;需要的包的相关文档 1. Barcode&#xff1a;https://pypi.org/project/python-barcode/0.8.1/ 2. Qrcode&#xff1a;https://pypi.org/project/qrcode/ 3. Zbar: https://pypi.org/project/pyzbar/ 4. Opencv: https://docs.opencv.org/3.4.11/ 5. OpenC…...

大数据-学习实践-5企业级解决方案

大数据-学习实践-5企业级解决方案 (大数据系列) 文章目录大数据-学习实践-5企业级解决方案1知识点2具体内容2.1小文件问题2.1.1 SequenceFile2.1.2 MapFile2.1.3 小文件存储计算2.2数据倾斜2.3 YARN2.3.1 YARN架构2.3.2 YARN调度器2.3.2 YARN多资源队列配置和使用2.4Hadoop官方…...

破解吲哚花菁素IR-808 N3,IR-808 azide,IR-808叠氮,酯溶性染料修饰叠氮基团,相关知识

基础产品数据&#xff08;Basic Product Data&#xff09;&#xff1a;CAS号&#xff1a;N/A中文名&#xff1a;IR-808叠氮英文名&#xff1a;IR-808 N3&#xff0c;IR-808 azideIR-808结构式&#xff08;Structural&#xff09;&#xff1a;详细产品数据&#xff08;Detailed …...

面试官:MQ的好处到底有哪些?

&#x1f497;推荐阅读文章&#x1f497; &#x1f338;JavaSE系列&#x1f338;&#x1f449;1️⃣《JavaSE系列教程》&#x1f33a;MySQL系列&#x1f33a;&#x1f449;2️⃣《MySQL系列教程》&#x1f340;JavaWeb系列&#x1f340;&#x1f449;3️⃣《JavaWeb系列教程》…...

事务机制:Redis能实现ACID属性吗?

ACID特性无需多言。我们知道关系数据库比如mysql可以实现事务的ACID特性&#xff0c;begin,commit,回滚实现。 那么redis可以实现ACID吗&#xff0c;结论是不能完全保证。 首先要知道redis通过MULTI关键字开启事务&#xff0c;中间一系列操作&#xff0c;加到操作队列中并不执…...

如何在 Apinto 实现 HTTP 与 gRPC 的协议转换(上)

什么是 gRPC 像 gRPC 是由 google 开发的一个高性能、通用的开源 RPC 框架&#xff0c;主要面向移动应用开发且基于 HTTP/2 协议标准而设计&#xff0c;同时支持大多数流行的编程语言。 gRPC 基于 HTTP/2 协议传输&#xff0c;而 HTTP/2 相比 HTTP1.x &#xff0c;有以下优势:…...

3分钟看完-丄-Python自动化测试【项目实战解析】经验分享

目录&#xff1a;导读 引言 自动化测试 背景 测试团队 测试体系发展 测试平台 自动化测试现状 现状一&#xff1a; 现状二&#xff1a; 现状三&#xff1a; 现状四&#xff1a; 现状五&#xff1a; 现状六&#xff1a; 失败的背景 失败的经历 失败总结 引言 内…...

Web漏洞-命令执行和代码执行漏洞

命令执行原理就是指用户通过浏览器或其他辅助程序提交执行命令&#xff0c;由于服务器端没有针对执行函数做过滤&#xff0c;导致在没有指定绝对路径的情况下就执行命令。漏洞成因它所执行的命令会继承WebServer的权限&#xff0c;也就是说可以任意读取、修改、执行Web目录下的…...

Towards Unsupervised Text Classification Leveraging Experts and Word Embeddings

Towards Unsupervised Text Classification Leveraging Experts and Word Embeddings Abstract 该论文提出了一种无监督的方法&#xff0c;使用每个文档中相关单词之间的文本相似度以及每个类别的关键字字典将文档分为几类。所提出的方法通过人类专业知识和语言模型丰富了类别…...

linux进程管理

进程管理 进程是启动的可执行程序的一个指令 1、进程简介 &#xff08;1&#xff09;进程的组成部分 已分配内存的地址空间安全属性&#xff0c;包括所有权凭据和特权程序代码的一个或多个执行线程进程状态 &#xff08;2&#xff09;程序和进程的区别 程序是一个静态的二进制…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

Java毕业设计:WML信息查询与后端信息发布系统开发

JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发&#xff0c;实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构&#xff0c;服务器端使用Java Servlet处理请求&#xff0c;数据库采用MySQL存储信息&#xff0…...

pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决

问题&#xff1a; pgsql数据库通过备份数据库文件进行还原时&#xff0c;如果表中有自增序列&#xff0c;还原后可能会出现重复的序列&#xff0c;此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”&#xff0c;…...

向量几何的二元性:叉乘模长与内积投影的深层联系

在数学与物理的空间世界中&#xff0c;向量运算构成了理解几何结构的基石。叉乘&#xff08;外积&#xff09;与点积&#xff08;内积&#xff09;作为向量代数的两大支柱&#xff0c;表面上呈现出截然不同的几何意义与代数形式&#xff0c;却在深层次上揭示了向量间相互作用的…...

HTTPS证书一年多少钱?

HTTPS证书作为保障网站数据传输安全的重要工具&#xff0c;成为众多网站运营者的必备选择。然而&#xff0c;面对市场上种类繁多的HTTPS证书&#xff0c;其一年费用究竟是多少&#xff0c;又受哪些因素影响呢&#xff1f; 首先&#xff0c;HTTPS证书通常在PinTrust这样的专业平…...

【1】跨越技术栈鸿沟:字节跳动开源TRAE AI编程IDE的实战体验

2024年初&#xff0c;人工智能编程工具领域发生了一次静默的变革。当字节跳动宣布退出其TRAE项目&#xff08;一款融合大型语言模型能力的云端AI编程IDE&#xff09;时&#xff0c;技术社区曾短暂叹息。然而这一退场并非终点——通过开源社区的接力&#xff0c;TRAE在WayToAGI等…...

李沐--动手学深度学习--GRU

1.GRU从零开始实现 #9.1.2GRU从零开始实现 import torch from torch import nn from d2l import torch as d2l#首先读取 8.5节中使用的时间机器数据集 batch_size,num_steps 32,35 train_iter,vocab d2l.load_data_time_machine(batch_size,num_steps) #初始化模型参数 def …...