C++多线程编程(第三章 案例3:把案例1改装成案例2的条件变量多线程方式)

news2025/2/27 17:04:12

由于案例1采用等待循环方式进行写入,如果更换成案例2的条件多线程方式,效率会大大增加,下面开始写出新的代码吧

主函数

/*

1、封装线程基类XThread控制线程启动和停止;
2、模拟消息服务器线程,接收字符串消息,并模拟处理;
3、通过Unique_lock和mutex互斥方位list<string> 消息队列
4、主线程定时发送消息给子线程;

*/

#include "XMsgSever.h"
#include <sstream>
#include <iostream>

using namespace std;

int main()
{
	XMsgSever server;
	server.Start();//启动子线程,调了Main入口,进入死循环消费信息了
	for (int i = 0; i < 10; i++)
	{
		stringstream ss;
		ss << "msg: " << i + 1;
		server.SendMsg(ss.str());
		this_thread::sleep_for(500ms);
	}
	server.Stop();//改用条件变量的时候,停止线程需要做更改,否则死锁等待

	printf("All done!\n");

	return 0;
}

XMsgSever类头文件,主要增加了Stop()函数重写部分

//XMsgSever.h
#pragma once
#include "XThread.h"
#include <list>
#include <mutex>
class XMsgSever:public XThread
{
public:
	//给当前线程发消息
	void SendMsg(std::string msg);

	void Stop() override;//在子函数中重载

private:
	void Main()override;//重写main,override检查名字是否写错

	
	std::list<std::string> msgs_;//消息队列缓冲

	std::mutex mux_;//互斥访问消息队列
	std::condition_variable cv_;//条件变量

};


XMsgSever类cpp文件,主要更改了类中的Main()函数,等待部分,使用了条件变量

//XMsgSever.cpp
#include "XMsgSever.h"
#include <iostream>

using namespace std;


void XMsgSever::SendMsg(std::string msg)
{//消息生产者
	
	unique_lock<mutex> lock(mux_);//为了保证list的线程安全,加锁
	msgs_.push_back(msg);
	lock.unlock();
	cv_.notify_one();//通知一个入口函数进行
}

void XMsgSever::Stop()
{
	//条件变量
	is_exit_ = true;
	cv_.notify_all();//通知所有线程,避免锁死了
	Wait();

}

void XMsgSever::Main()
{//消息消费者
	while (!is_exit())
	{
		//this_thread::sleep_for(10ms);
		unique_lock<mutex> lock(mux_);
		//cv_.wait(lock);//条件变量等待,条件满足就直接执行。如果这样写,最后可能一直阻塞在这里
		cv_.wait(lock, [this] {
			cout << "wait cv" << endl;
			if (is_exit())return true;//如果退出了,需要退出

			return !msgs_.empty(); //有内容,返回false
			});//条件变量等待,条件满足就直接执行

		if (msgs_.empty())
		{//如果没有消息,则continue
			continue;
		}
		while (!msgs_.empty())
		{//消息处理业务逻辑
			cout << "recv: " << msgs_.front().c_str() << endl;
			msgs_.pop_front();
		}

	}

}

XThread 类头文件中将is_exit_变量设置为了protected,为了在子类中可以访问这个变量

//XThread.h

#pragma once
#include <thread>

//基类
class XThread
{
public:
	virtual void Start();//启动线程
	virtual void Stop();//设置线程退出标志,并等待
	virtual void Wait();//等待
	virtual bool is_exit();//线程是否退出

protected:
	bool is_exit_ = false;//放到这里来,派生类可以访问这个变量

private:
	virtual void Main() = 0;//线程入口,纯虚函数,子函数必须单独实现
	
	std::thread th_;

};


XThread 类cpp文件没有做任何更改

//
#include "XThread.h"

using namespace std;//在CPP中引用using namespace
void XThread::Start()//启动线程
{
	is_exit_ = false;//不要退出
	th_ = thread(&XThread::Main,this);

}
void XThread::Stop()//设置线程退出标志,并等待
{
	is_exit_ = true;
	Wait();

}
void XThread::Wait()//等待
{
	if (th_.joinable())
	{
		th_.join();
	}

}
bool XThread::is_exit()//线程是否退出
{
	return is_exit_;
}

程序可以顺利执行完,执行效果如下图
在这里插入图片描述

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

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

相关文章

11-JVM调优实战-1

上一篇&#xff1a;10-JVM调优工具详解 1.垃圾回收统计 jstat -gc pid 最常用&#xff0c;可以评估程序内存使用及GC压力整体情况 S0C&#xff1a;第一个幸存区的大小&#xff0c;单位KBS1C&#xff1a;第二个幸存区的大小S0U&#xff1a;第一个幸存区的使用大小S1U&#x…

HD系列边缘网关,助力工商业储能发展!

HD系列边缘网关具备低功耗、高性能、接口丰富等特点&#xff0c;可以实现如通信规约转换、远程调度、智能监测、通信管理等多种应用&#xff0c;适用于储能系统的能源管理系统。 1.1硬件接口 该产品板载瑞芯微 RK3568 处理器&#xff0c;可选配2G16G/432 等配置。机壳采用标准 …

zabbix使用 -- 添加监控节点、自定义监控项、触发器

目录 页面中的一些概念配置agent服务来获取目标主机数据对nginx服务器进行监控在网页中添加一台配置 自定义监控项 -- 以监控nginx为例1、开启nginx本身的统计功能2、编写脚本采集数据3、在zabbix-server里获取数据监控ssh进程监控cron进程 触发器报警1、注册一个企业微信2、微…

Spring MVC 请求映射路径的配置,实现前后端交互

目录 一、什么是请求映射路径 二、Spring MVC的请求参数 三、日期类型的参数传递 四、Spring MVC如何响应 JSON 数据 一、什么是请求映射路径 在Spring MVC中&#xff0c;请求映射路径&#xff08;Request Mapping Path&#xff09;是指与特定的请求处理方法关联的URL路径…

改善购买后客户体验的 7 种方法

购买后的客户体验涉及客户从您的品牌购买产品后的互动和体验。客户体验从第一个接触点开始&#xff0c;并影响他们的购买决策。但购买后的客户体验有助于留住客户并建立品牌忠诚度。这就是为什么它是您公司发展的核心。贝恩公司&#xff08;Bain & Company&#xff09;的研…

品牌渠道中的价值治理思路介绍

为什么要治理渠道价格&#xff1f; 价格的高低会影响产品的销量&#xff0c;间接影响品牌的发展&#xff0c;同时低价会存在传播性&#xff0c;不低价的店铺会受低价店铺的影响&#xff0c;为了销量会选择低价跟价&#xff0c;当低价链接不断增加&#xff0c;那渠道势必会越来…

简单聊聊Innodb崩溃恢复那些事

简单聊聊Innodb崩溃恢复那些事 Buffer Pool 整体架构Buffer Pool 管理策略redo 日志redo log fileMini-TransactionCheckPoint部分写出问题 崩溃恢复 undo日志整体结构日志格式记录格式purge回滚 总结额外参考 本文想用简单精炼的语言将Innodb崩溃恢复那些事情好好拾到拾到&…

轻松搭建自己本地专有的ChatGPT

近期发现了一个项目&#xff0c;它的前身是ChatGLM&#xff0c;在我之前的博客中有关于ChatGLM的部署过程&#xff0c;本项目在前者基础上进行了优化&#xff0c;可以基于当前主流的LLM模型和庞大的知识库&#xff0c;实现本地部署自己的ChatGPT&#xff0c;并可结合自己的知识…

Web of Science怎么用有哪些功能

Web of Science你不可不知道的数据库。作为全球最大的学术搜索引擎之一&#xff0c;Web of Science涵盖了众多学科领域&#xff0c;为科研人员提供了全面、高品质的学术资源。本文将详细介绍Web of Science的主要功能及使用步骤&#xff0c;希望可以帮助您更好地利用这一强大的…

揭秘人物稿件写作技巧:如何让你的文字生动起来?

如何写出一篇高质量的人物稿件&#xff0c;让读者沉浸其中&#xff0c;感受到稿件中人物的生动形象呢&#xff1f;本文伯乐网络传媒将从以下几个方面进行探讨&#xff1a;选材、结构、语言和深度。 一、选材&#xff1a;选取热门而有吸引力的话题或爆点 人物稿件的选材至关重要…

React 类式组件

0x00 前言 CTF 加解密合集CTF Web合集网络安全知识库 文中工具皆可关注 皓月当空w 公众号 发送关键字 工具 获取 0x01 类式组件 1.创建类式组件 这里需要注意的是需要继承一下React.Component class MyComponent extends React.Component{}实现render方法 class MyCompone…

一文带你抢先了解腾讯云AI代码助手

背景 随着近年来人工智能技术的广泛应用&#xff0c;各个领域和行业纷纷探索如何利用AI辅助生产与开发。软件开发者也在努力提升开发体验&#xff0c;借助AI的能力进行编码、调试、测试和评审。Github Copilot、Codeium、Amazon CodeWhisperer等都是这个领域的杰出代表。为了满…

关于测试的思考-质量保障体系

一、质量保障体系 1、质量保障体系说明 2、如何构建质量保障体系 3、质量保障案例 二、敏捷开发下的软件测试 1、互联网公司敏捷流程的实践 2、提升测试上线质量&#xff08;质量右移&#xff09;&#xff1a; 灰度方式&#xff1a;根据机器&#xff0c;根据用户画像&#xff…

RTPV70-30、RTPV72-30电磁比例插装阀放大器

RTSP08-20、RTSP10-20、RTSP12-20、RTSP08-22、RTHSP09-30、RTPV70-30、RTPV72-30电磁比例插装阀额定电磁线圈适合连续工作&#xff0c;应急手控选件&#xff0c;外置式比例放大器&#xff0c;效湿式衔铁结构&#xff0c;可选IP69K防水E型线圈&#xff0c;工业通用阀孔。

vcpkg方式安装zlmediakit

主要参考: https://github.com/ZLMediaKit/ZLMediaKit/wiki/vcpkg%E6%96%B9%E5%BC%8F%E5%AE%89%E8%A3%85zlmediakit vcpkg的相关配置不在本文论述。很多库或源码下载不下来&#xff0c;通过第三方下载后放在download目录下&#xff0c;名称要和vcpkg期望的一致。可通过云服务器…

“五度晟企通”企业发展服务平台正式发布,帮扶企业行稳致远!

在数字中国建设的大背景下&#xff0c;“五度易链”以企业实际发展需求为牵引&#xff0c;以帮扶企业行稳致远为目标&#xff0c;基于全体量产业大数据&#xff0c;运用NLP、AI等新一代信息技术&#xff0c;打造了数字化ToB企业发展服务平台“五度晟企通”&#xff0c;旨在以数…

Java重要知识点

Java JVM 参考&#xff1a;https://www.kuangstudy.com/bbs/1557549426359590914 请你谈谈你对jvm的理解&#xff1f;Java8虚拟机和之前的变化更新&#xff1f;什么是OOM&#xff1f;什么是栈溢出StackOverFlowError&#xff1f;怎么分析&#xff1f;jvm的常见调优参数有哪些&…

大数据如何应用于业务和决策?_光点科技

大数据已经成为当今商业和决策制定中的一个关键因素。随着互联网的普及和技术的不断进步&#xff0c;我们生产的数据量呈指数级增长。这些数据不仅包括来自社交媒体、传感器、移动设备等各种来源的信息&#xff0c;还包括过去难以存储和分析的结构化和非结构化数据。如何利用这…

spring boot 使用AOP+自定义注解+反射实现操作日志记录修改前数据和修改后对比数据,并保存至日志表

一、添加aop starter依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency>二&#xff1a;自定义字段翻译注解。&#xff08;修改功能时&#xff0c;需要显示如…

高压放大器在制备功能材料中的应用

高压放大器在制备功能材料中具有广泛的应用。功能材料是一类具有特殊性能和功能的材料&#xff0c;可以在各个领域中发挥重要作用&#xff0c;如能源存储、电子、光电、催化等。高压放大器在制备功能材料的研究和应用中起到关键的作用&#xff0c;本文将介绍高压放大器在制备功…