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

Studying-多线程学习Part3 - condition_variable与其使用场景、C++11实现跨平台线程池

来源:多线程学习

目录

condition_variable与其使用场景 

生产者与消费者模型

C++11实现跨平台线程池 


condition_variable与其使用场景 

生产者与消费者模型

生产者-消费者模式是一种经典的多线程设计模式,用于解决多个线程之间的数据共享和协作问题。在生产者-消费者模式中,有两类线程:生产者线程和消费者线程。它们之间通过共享一个缓冲区(或队列)来协作,生产者将数据放入缓冲区,消费者从缓冲区取出数据并进行处理。

生产者-消费者模式的主要目标是实现生产者和消费者之间的解耦,使它们可以独立地进行工作,从而提高系统的性能和可维护性。

condition_variable的步骤如下:

  1. 创建一个condition_variable对象
  2. 创建一个互斥锁 mutex 对象,用来保护共享资源的访问。
  3. 在需要等待条件变量的地方:使用unique_lock<mutex>对象锁定互斥锁,并调用condition_variable::wait()、condition_variable::wait_for()或condition_variable::wait_until()函数等待条件变量。

  4. 在其他线程中需要通知等待的线程时,调用condition_variable::notify_one()或condition_variable::notify_all()函数通知等待的线程。

代码参考:

#include <iostream>
#include <thread>
#include <mutex>
#include <string>#include <condition_variable>
#include <queue>
using namespace std;queue<int> g_queue; //任务队列
condition_variable g_cv;
mutex mtx;//实现生产者
void Producer() {for (int i = 0; i < 10; ++i) {{unique_lock<mutex> lock(mtx);g_queue.push(i);//加任务的时候哦,需要通知消费者来取任务g_cv.notify_one(); cout << "Producer: " << i << endl;}this_thread::sleep_for(chrono::microseconds(100)); //休眠100ms}
}//实现消费者
void Consumer() {while (1) {unique_lock<mutex> lock(mtx);//如果队列为空,理应需要等待//第二个参数是函数指针(可以用lambda表达式)返回的true则不堵塞,false则阻塞,注意阻塞的时候会释放资源所以不会发生死锁g_cv.wait(lock, []() {return !g_queue.empty(); });int value = g_queue.front();g_queue.pop();cout << "Consumer:" << value << endl;}
}int main() {thread t1(Producer);thread t2(Consumer);t1.join();t2.join();return 0;
}

C++11实现跨平台线程池 

线程池符合的就是生产者和消费者模型。线程池提前维护一个线程的数组和一个任务队列,不同的让线程去完成队列里的任务。

使用线程池可以解决不断销毁创建线程的消耗。

代码参考:

//实现线程池
#include <iostream>
#include <thread>
#include <mutex>
#include <string>
#include <condition_variable> //条件变量
#include <queue>
#include <thread>
#include<functional> //对象包装器
using namespace std;//创先线程池的类
class ThreadPool {
public://构造函数ThreadPool(int numThreads) : stop(false) {for (int i = 0; i < numThreads; i++) {threads.emplace_back([this] {while (1) {unique_lock<mutex> lock(mtx); //互斥锁,因为线程是操作任务队列的condition.wait(lock, [this] { //判断任务队列里面是否有任务,且是否停止return !tasks.empty() || stop;});if (stop && tasks.empty()) { //如果线程终止了,则结束线程return;}function<void()> task(move(tasks.front())); //拷贝构造,但是使用move能够防止赋值tasks.pop();lock.unlock(); //取完任务之后,解锁,让其他线程可以接续取任务task();}});}}//析构函数~ThreadPool() {//手动加{}提供作用域{unique_lock<mutex> lock(mtx);stop = true;}condition.notify_all(); //通知线程完成所有任务for (thread& t : threads) { //这个地方要使用引用,因为线程是不可以复制的t.join();}}//加任务,加函数,使用模版可以实现可变参数template<class F,class... Args>void enqueue(F&& f, Args&&...args) { //&&万能引用function<void()> task = bind(forward<F>(f), forward<Args>(args)...);{unique_lock <mutex> lock(mtx);tasks.emplace(move(task));}condition.notify_one();}private:vector<thread> threads; //线程数组queue<function<void()>> tasks; //任务队列,队列里面包含的是函数模版mutex mtx; //互斥量condition_variable condition; //条件变量bool stop;};int main() {ThreadPool pool(4);for (int i = 0; i < 10; i++) {pool.enqueue([i] {cout << "task: " << i << " start" << endl;this_thread::sleep_for(chrono::seconds(1));cout << "task: " << i << " down" << endl;});}return 0;
}

知识点汇总:

1. thread线程库:vector<thread> threads; //线程数组

2.function函数模版:

3.mutex互斥锁

4.condtion_variable 条件变量:解决生产者消费者问题

5.lambda表达式-匿名函数

6.move移动语义

7.template<class F, class...Args>

8.&&右值引用,万能引用

9.bind函数适配器,绑定函数和函数参数

10.forward完美转发,配合&&实现万能引用

相关文章:

Studying-多线程学习Part3 - condition_variable与其使用场景、C++11实现跨平台线程池

来源&#xff1a;多线程学习 目录 condition_variable与其使用场景 生产者与消费者模型 C11实现跨平台线程池 condition_variable与其使用场景 生产者与消费者模型 生产者-消费者模式是一种经典的多线程设计模式&#xff0c;用于解决多个线程之间的数据共享和协作问题。…...

开发自定义starter

环境&#xff1a;Spring Cloud Gateway 需求&#xff1a;防止用户绕过网关直接访问服务器&#xff0c;用户只需引入依赖即可。 1、创建项目 首先创建一个spring boot项目 2、配置pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xm…...

Vue2电商平台(五)、加入购物车,购物车页面

文章目录 一、加入购物车1. 添加到购物车的接口2. 点击按钮的回调函数3. 请求成功后进行路由跳转(1)、创建路由并配置路由规则(2)、路由跳转并传参(本地存储) 二、购物车页面的业务1. uuid生成用户id2. 获取购物车数据3. 计算打勾商品总价4. 全选与商品打勾(1)、商品全部打勾&a…...

众数信科 AI智能体政务服务解决方案——寻知智能笔录系统

政务服务解决方案 寻知智能笔录方案 融合民警口供录入与笔录生成需求 2分钟内生成笔录并提醒错漏 助办案人员二次询问 提升笔录质量和效率 寻知智能笔录系统 众数信科AI智能体 产品亮点 分析、理解行业知识和校验规则 AI实时提醒用户文书需注意部分 全文校验格式、内容…...

Redis篇(面试题 - 连环16炮)(持续更新迭代)

目录 目录 目录 &#xff08;第一炮&#xff09;一、Redis&#xff1f;常用数据结构&#xff1f; 1. 项目里面到了Redis&#xff0c;为什么选用Redis&#xff1f; 2. Redis 是什么&#xff1f; 3. Redis和关系型数据库的本质区别有哪些&#xff1f; 4. Redis 的线程模型…...

selenium元素定位

find_element和find_elements 元素定位有两个表达式&#xff0c;分别为find_element()和find_elements()&#xff0c;它们的不同点如下&#xff1a; find_element()&#xff1a;找出的为单个元素&#xff0c;若有多个元素为同一表达式&#xff0c;则默认定位第一个元素&#…...

美畅物联丨视频汇聚从“设”开始:海康威视摄像机设置详解

在运用畅联云平台进行视频汇聚与监控管理时&#xff0c;海康威视的安防摄像机凭借其卓越的性能与广泛的应用兼容性&#xff0c;成为了众多用户的首选产品。海康威视摄像机参数设置与调试对于实现高效的安防监控至关重要。今天&#xff0c;让我们一同深入学习海康摄像机的参数设…...

聊天机器人羲和的代码04

进一步完善和优化聊天机器人GUI,使其更加丰富和美观,采取了以下措施: 添加图标:为应用程序添加一个图标。 调整布局:进一步优化布局,使其更加美观。 增加样式:使用更多的样式和主题来提升视觉效果。 添加动画:增加加载动画以提高用户体验。 优化控件:使用更现代的控件…...

Linux安装配置Jupyter Lab并开机自启

文章目录 1、安装配置jupyter lab首先需要使用pip3安装&#xff1a;生成配置文件和密码&#xff1a; 2、设置开机自启首先通过which jupyter查询到可执行文件路径&#xff1a;设置自启服务&#xff1a; 1、安装配置jupyter lab 首先需要使用pip3安装&#xff1a; pip3 instal…...

Java基础——`UUID.randomUUID()` 方法详细介绍

这里写自定义目录标题 UUID.randomUUID() 方法详细介绍1. 概述2. UUID 的结构与格式UUID 的 128 位结构划分&#xff1a; 3. UUID.randomUUID() 方法详解3.1 方法签名3.2 使用示例3.3 生成原理3.4 随机数生成的范围3.5 随机字符的取值范围 4. UUID 的版本与特性4.1 UUID 版本 4…...

前端面试常见手写代码题【详细篇】

文章目录 前言&#xff1a;防抖节流函数柯里化函数组合instanceof 实现实现new操作符的行为深拷贝继承实现&#xff1a;手写Promise数组中常见函数的实现 前言&#xff1a; 在前端面试中&#xff0c;经常会遇到要求手写的代码的题目&#xff0c;主要是考察我们的编程能力、和对…...

当代最厉害的哲学家改名大师颜廷利:北京、上海、广州和深圳房价精准预测

在2024年国庆节期间&#xff0c;北京、上海、广州和深圳的房地产市场异常活跃。作为山东济南籍的国际易学权威颜廷利教授&#xff0c;连续收到了这些大城市客户的感谢信和电话。 来自北京的王先生在信中写道&#xff1a;“非常感谢颜廷利教授这几年来对我们的鼓励和支持。在经历…...

MySQL常用指令码

本文精心挑选了一系列MySQL指令码&#xff0c;助你提升资料库效率、解决常见问题&#xff0c;让你的资料储存体验更加高效、可靠。 常用功能指令码 1.汇出整个资料库 mysqldump - u 使用者名称- p – default - character - set latin1 资料库名>汇出的档名(资料库预设编…...

OpenHarmony(鸿蒙南向开发)——轻量系统内核(LiteOS-M)【扩展组件】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… C支持 基本概念 C作为目前使用最广泛的编程语言之一&#xff0c;…...

官方ROM 免费下载! 王者归来! 华为秘盒media Q M310(续)

最近在捣鼓电视盒子&#xff0c; 前帖讨论了如何拯救华为华为秘盒media Q M310&#xff0c; 详情请点击这里&#xff01; https://blog.csdn.net/weixin_62598385/article/details/142658048 CSDN上有精简版的M310 ROM下载&#xff0c; 但是我点不进去&#xff0c; 要收年费&am…...

【Docker】05-Docker部署前端项目

1. nginx.conf worker_processes 1;events {worker_connections 1024; }http {include mime.types;default_type application/json;sendfile on;keepalive_timeout 65;server {listen 18080;# 指定前端项目所在的位置location / {root /usr/share/nginx…...

SQL进阶技巧:如何优化NULL值引发的数据倾斜问题?

目录 0 场景描述 1 问题分析 1.1 问题剖析 1.2 解决方案 2 小结 0 场景描述 实际业务中有些大量的null值或者一些无意义的数据参与到计算作业中,表中有大量的null值,如果表之间进行join操作,就会有shuffle产生,这样所有的null值都会被分配到一个reduce中,必然产生数…...

【09】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-Class类基础全解(属性、方法、继承复用、判断)

序言&#xff1a; 本文详细讲解了关于我们在程序设计中所用到的class类的各种参数及语法。 笔者也是跟着B站黑马的课程一步步学习&#xff0c;学习的过程中添加部分自己的想法整理为笔记分享出来&#xff0c;如有代码错误或笔误&#xff0c;欢迎指正。 B站黑马的课程链接&am…...

快速提升波段交易技能:4种实用策略分享

每个交易员的交易偏好是各不相同的&#xff0c;有人偏爱短线交易的迅速反应&#xff0c;有人钟情于中长线的稳健布局&#xff0c;还有人则热衷于波段交易的灵活操作。我们经常探讨短线与中长线的策略&#xff0c;但你了解波段交易的策略吗&#xff1f; 波段交易是什么&#xf…...

LeetCode 11 Container with Most Water 解题思路和python代码

题目&#xff1a; You are given an integer array height of length n. There are n vertical lines drawn such that the two endpoints of the ith line are (i, 0) and (i, height[i]). Find two lines that together with the x-axis form a container, such that the co…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

对象回调初步研究

_OBJECT_TYPE结构分析 在介绍什么是对象回调前&#xff0c;首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例&#xff0c;用_OBJECT_TYPE这个结构来解析它&#xff0c;0x80处就是今天要介绍的回调链表&#xff0c;但是先不着急&#xff0c;先把目光…...