如何优雅的退出线程(condition_variable )

news2024/11/20 15:35:38

C++多线程并发编程入门(目录)

使用条件变量来实现在析构函数中再次向线程发出一次notify,之后join 线程,等等线程安全退出。

#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <string_view>
#include <mutex>
#include <queue>
#include <sstream>

using namespace std;
class Logger
{
public:
	Logger();
	virtual ~Logger();
	Logger(const Logger& src) = delete;
	Logger& operator=(const Logger& rhs) = delete;
	void log(std::string entry);
private:
	void processLogging();
	std::mutex m_mutex;
	std::condition_variable m_condition_var;
	std::queue<std::string> m_queue;
	std::thread m_thread;
	bool m_have_to_exit = false;
};
Logger::Logger()
{
	m_thread = thread{ &Logger::processLogging, this };
	cout << "Logger::Logger()" << endl;
}

void Logger::log(std::string entry)
{
	unique_lock<std::mutex> lock(m_mutex);
	m_queue.push(entry);
	m_condition_var.notify_all();
}

Logger::~Logger()
{
	cout << "Logger::~Logger()" << endl;
	{
		unique_lock<std::mutex> lock(m_mutex);
		m_have_to_exit = true;
		m_condition_var.notify_all();
	}
	m_thread.join();
}

void Logger::processLogging()
{
	cout << "Logger::processLogging() begin run...." << endl;
	ofstream logFile("log.txt");

	if (logFile.fail())
	{
		cerr << "Failed to open logfile." << endl;
		return;
	}

	unique_lock<std::mutex> lock(m_mutex);
	while (true)
	{
		if (!m_have_to_exit)
		{
			m_condition_var.wait(lock); 
		}
		lock.unlock();
		while (true)//循环处理队列直到为空
		{
			lock.lock();
			if (m_queue.empty())
			{
				break;
			}
			else
			{
				logFile << m_queue.front() << endl;
				m_queue.pop();
			}
			lock.unlock();
		}
		if (m_have_to_exit)
		{
			cout << "m_have_to_exit is true.\n";
			break;
		}
	}
	cout << "Logger::processLogging() exited." << endl;
}

void logSomeMessage(int id, Logger& logger)
{
	for (int i = 0; i < 5; ++i)
	{
		stringstream ss;
		ss << " Thread " << id<< " log message the " << i <<"th times.";
		logger.log(ss.str());
	}
}

int main()
{
	cout << "hello main.\n";
	Logger logger;
	cout << "ready to create producer" << endl;
	vector<thread> threads;
	for (int i = 0; i < 5; ++i)
	{
		cout << "times: " << i << "\n";
		threads.emplace_back(logSomeMessage, i, ref(logger));
	}
	for (auto& t : threads)
	{
		t.join();
	}
	cout << "main exited.\n";
	return 0;
}

程序输出:

文件输出:

 Thread 1 log message the 0th times.
 Thread 0 log message the 0th times.
 Thread 1 log message the 1th times.
 Thread 2 log message the 0th times.
 Thread 0 log message the 1th times.
 Thread 1 log message the 2th times.
 Thread 2 log message the 1th times.
 Thread 0 log message the 2th times.
 Thread 1 log message the 3th times.
 Thread 2 log message the 2th times.
 Thread 0 log message the 3th times.
 Thread 1 log message the 4th times.
 Thread 2 log message the 3th times.
 Thread 0 log message the 4th times.
 Thread 2 log message the 4th times.
 Thread 4 log message the 0th times.
 Thread 3 log message the 0th times.
 Thread 3 log message the 1th times.
 Thread 4 log message the 1th times.
 Thread 3 log message the 2th times.
 Thread 4 log message the 2th times.
 Thread 3 log message the 3th times.
 Thread 4 log message the 3th times.
 Thread 3 log message the 4th times.
 Thread 4 log message the 4th times.

参考:如何优雅地退出线程?_std::thread exit_帮主写书的博客-CSDN博客

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

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

相关文章

PerformanceOne一站式性能测试平台

PerformanceOne&#xff08;简称&#xff1a;P-One&#xff09;是泽众软件自主研发的一套一站式性能测试平台软件产品。 该产品采用 B/S 架构开发&#xff0c;实现了集管理、设计、压测、监控以及分析于一体的全方位性能测试解决方案。可有效提升性能测试技术能力&#xff0c;…

拥抱数字化时代SOP电子作业指导书系统助力企业差异化竞争

在如今的竞争激烈的市场环境中&#xff0c;企业要想在同等条件下脱颖而出&#xff0c;差异化竞争成为了关键。然而&#xff0c;与硬件相比&#xff0c;软件的差异化更具有决定性的作用。而软件的差异化往往体现在细节上&#xff0c;而不是大的战略方面。而如何将这些细节进行量…

深入理解C#中委托的使用及不同类型委托的应用示例

在C#中&#xff0c;委托是一种强大而灵活的机制&#xff0c;可以引用一个或多个方法&#xff0c;并允许以类似函数指针的方式进行调用。委托在事件处理、回调函数和多线程编程等场景中非常有用。本文将深入探讨C#中委托的使用&#xff0c;并介绍不同类型委托的应用示例。 目录…

怎么解决IT运维管理痛点?运维工单系统如何提高企业运营效率?

随着企业信息化的飞速发展&#xff0c;IT系统的规模和复杂性也在迅速增长。然而&#xff0c;传统的IT运维管理方式往往难以满足现代企业的需求&#xff0c;存在着许多痛点。   首先&#xff0c;传统的运维管理方式效率低下&#xff0c;缺乏有效的IT资产管理和监控手段&#x…

高效畅通的iOS平台S5配置指南

在iOS平台上&#xff0c;使用S5代理ip访问互联网是一种非常有用的技巧。无论是为了保证隐私安全&#xff0c;还是解决网络限制问题&#xff0c;S5代理ip都能为您提供更快、更稳定的互联网访问体验。本文将为您详细介绍如何在iOS平台上配置和使用S5代理ip&#xff0c;让您的网络…

jarvisoj_level3_x64

jarvisoj_level3_x64 Arch: amd64-64-little RELRO: No RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)64位&#xff0c;只开了nx ssize_t vulnerable_function() {char buf[128]; // [rsp0h] [rbp-80h] BYREFwrite(1, "Inp…

铁路设备屡遭破坏!RFID电子锁实现铁路防护网破坏实时报警管理

铁路防护网是铁路运输中保障安全的重要组成部分&#xff0c;然而&#xff0c;铁路设备被破坏的情况时有发生&#xff0c;给铁路运输带来了严重的安全隐患和经济损失。 一、铁路防护网面临的挑战 铁路防护网作为铁路运输的重要保障措施&#xff0c;时刻面临着破坏行为的威胁。…

win10 关闭edge跳转IE浏览器

按下windows键&#xff0c;搜索控制面板 右上角输入IE 点击IE 高级中取消下红框选择即可

mapbox鼠标滑过高亮要素

成果图 实现方法 这里借鉴了官网这个例子 https://docs.mapbox.com/mapbox-gl-js/example/hover-styles/ 这里是图层的样式配置&#xff0c;通过改变select的true和false&#xff0c;来控制渲染的颜色和宽度 paint: {line-opacity: 1,line-color: [case,[boolean, [feature-st…

算法通过村第七关-树(递归/二叉树遍历)黄金笔记|迭代遍历

文章目录 前言1. 迭代法实现前序遍历2. 迭代法实现中序遍历3. 迭代法实现后序遍历总结 前言 提示&#xff1a;在一个信息爆炸却多半无用的世界&#xff0c;清晰的见解就成了一种力量。 --尤瓦尔赫拉利《今日简史》 你是不是觉得上一关特别简单&#xff0c;代码少&#xff0c;背…

MySQL 高级语句 Part1(进阶查询语句+MySQL数据库函数+连接查询)

高级语句 第一部分 一、MySQL进阶查询语句1.1 select ----显示表格中一个或数个字段的所有数据记录1.2 distinct ----不显示重复的数据记录1.3 where ----有条件查询1.4 and or ----且 或1.5 in----显示已知的值的数据记录1.6 between----显示两个值范围内的数据记录1.7 通配符…

如何选择最适转录本序列构建过表达质粒

以构建绵羊 PPARG 基因过表达质粒为例 主要利用的数据库有 NCBI 和 Uniprot 数据库&#xff0c;首先在 NCBI 检索绵羊 PPARG 基因信息&#xff0c;可以发现绵羊 PPARG 有8个转录本&#xff0c;而人就更多了&#xff0c;有16个转录本。这时就需要明确一个概念&#xff0c;构建过…

CFCA证书 申请 流程(二)

关于CFCA证书的介绍&#xff0c;可参考上一篇文章&#xff1a;CFCA证书 申请 流程&#xff08;一&#xff09;_身价五毛的博客-CSDN博客 CFCA测试证书 申请流程 测试证书主要用于在测试环境对所需功能进行验证&#xff0c;例如HTTPS访问等。 首先&#xff0c;向CFCA的支持邮…

【论文笔记】NeRF-RPN: A general framework for object detection in NeRFs

原文链接&#xff1a;https://arxiv.org/abs/2211.11646 1. 引言 NeRF模型能直接从给定的RGB图像和相机姿态学习3D场景的NeRF表达。本文提出NeRF-RPN&#xff0c;使用从NeRF模型提取的辐射场和密度&#xff0c;直接生成边界框提案。 3. 方法 如图所示&#xff0c;本文的方法有…

TouchGFX之画布控件

TouchGFX的画布控件&#xff0c;在使用相对较小的存储空间的同时保持高性能&#xff0c;可提供平滑、抗锯齿效果良好的几何图形绘制。 TouchGFX 设计器中可用的画布控件&#xff1a; LineCircleShapeLine Progress圆形进度条 存储空间分配和使用​ 为了生成反锯齿效果良好的…

「UG/NX」BlockUI 选择小平面区域 Select Facet Region

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「UG/NX」BlockUI集合&#x1f4da;全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C」C/C程序设计「Win」Windows程序设计「DSA」数据结构与算法「File」数据文件格式 目录 控件说…

深入探究序列化与反序列化:原理、应用和最佳实践

目录 什么是对象的序列化和反序列化序列化步骤反序列化步骤案例演示Java中哪些字段不能序列化序列化与反序列化的重要性序列化与反序列化的应用场景 什么是对象的序列化和反序列化 序列化&#xff08;Serialization&#xff09;是指将对象转化为字节流的过程&#xff0c;以便于…

点燃创意,发掘绘图潜能——FireAlpaca for Mac专业绘图软件

无论您是一位艺术家、插画师还是爱好绘图的人&#xff0c;寻找一款功能强大且易于使用的绘图软件都是必不可少的。而FireAlpaca for Mac作为一款专为Mac用户设计的专业绘图软件&#xff0c;将点燃您的创意&#xff0c;帮助您发掘绘图的潜能。 FireAlpaca for Mac拥有丰富的工具…

Linux,计算机网络,数据库

Linux&#xff0c;计算机网络&#xff0c;数据库&#xff0c;操作系统 一、Linux1、linux查看进程2、linux基本命令3、top命令、查看磁盘 二、计算机网络1、HTTP的报文段请求 Repuest响应 Response 2、HTTP用的什么连接3、TCP的三次握手与四次挥手三次握手四次挥手 4、在浏览器…

【RabbitMQ实战】02 生产者和消费者示例

在上一节中&#xff0c;我们使用docker部署了RabbitMQ&#xff0c;这一节我们将写一段生产者和消费者的代码。将用到rabbitmq的原生API来进行生产和发送消息。 一、准备工作 开始前&#xff0c;我们先在RabbitMQ控制台建相好关的数据 本机的RabbitMQ部署机器是192.168.56.201…