C++11中条件标量和互斥锁应用出现死锁思考

news2024/11/16 1:25:06

条件变量和互斥锁在多线程同步过程中经常被使用,以下测试程序测试其使用。

目录

1.测试程序1

2.测试程序2 

 3.运行结果思考


1.测试程序1

#include <mutex>
#include <deque>
#include <iostream>
#include <thread>
#include <condition_variable>

class MCTest {
public:
	MCTest() : m_work(true), m_max_num(30), m_next_index(0) {
	}
	
	void producer_thread() {
		while (m_work) {
			std::this_thread::sleep_for(std::chrono::milliseconds(500));
			std::unique_lock<std::mutex> lk(m_cvMutex);
			m_cv.wait(lk);
			m_data.push_back(m_next_index++);
			std::cout << "producer " << m_next_index << ", queue size: " << m_data.size() << std::endl;
			m_cv.notify_all();
		}
	}
	void consumer_thread() {
		while (m_work) {
            std::unique_lock<std::mutex> lk(m_cvMutex);
            m_cv.wait(lk);
		    int data = m_data.front();
		    m_data.pop_front();
		    std::cout << "consumer " << data << ", deque size: " << m_data.size() << std::endl;
		    m_cv.notify_all();
		}
	}
private:
	bool m_work;
	std::mutex m_cvMutex;
	std::condition_variable m_cv;
	std::deque<int> m_data;
	size_t m_max_num;
	int m_next_index;
};

int main() {
	MCTest obj;
	std::thread tp = std::thread(&MCTest::producer_thread, &obj);
	std::thread tc = std::thread(&MCTest::consumer_thread, &obj);
    tp.join();
    tc.join();
	return 0;
}

运行结果:

2.测试程序2 

#include <mutex>
#include <deque>
#include <iostream>
#include <thread>
#include <condition_variable>

class MCTest {
public:
	MCTest() : m_work(true), m_max_num(30), m_next_index(0) {
	}
	
	void producer_thread() {
		while (m_work) {
			std::this_thread::sleep_for(std::chrono::milliseconds(500));
			std::unique_lock<std::mutex> lk(m_cvMutex);
			m_cv.wait(lk, [this]() -> bool { return this->m_data.size() < this->m_max_num; });
			m_data.push_back(m_next_index++);
			std::cout << "producer " << m_next_index << ", queue size: " << m_data.size() << std::endl;
			m_cv.notify_all();
		}
	}
	void consumer_thread() {
		while (m_work) {
            std::unique_lock<std::mutex> lk(m_cvMutex);
            m_cv.wait(lk, [this] { return !this->m_data.empty(); });
		    int data = m_data.front();
		    m_data.pop_front();
		    std::cout << "consumer " << data << ", deque size: " << m_data.size() << std::endl;
		    m_cv.notify_all();
		}
	}
private:
	bool m_work;
	std::mutex m_cvMutex;
	std::condition_variable m_cv;
	std::deque<int> m_data;
	size_t m_max_num;
	int m_next_index;
};

int main() {
	MCTest obj;
	std::thread tp = std::thread(&MCTest::producer_thread, &obj);
	std::thread tc = std::thread(&MCTest::consumer_thread, &obj);
    tp.join();
    tc.join();
	return 0;
}

运行结果:

 3.运行结果思考

为什么测试1程序没有任何输出,出现死锁,而程序2正常交替执行?

程序1条件变量在得到通知之前会一直wait,如果线程1获取了锁后,阻塞于wait调用,释放了互斥锁,等待通知。此时线程2执行,线程2获取锁后,阻塞于阻塞于wait调用,并释放互斥锁,等待唤醒。本质上是处于死锁状态。

程序2条件变量处于wait阻塞时,除了得到通知会解除阻塞外,第二个参数为true时,wait函数也会返回,所以避免了死锁的存在。

总结一下,wait函数参数2含义如下:

(1)如果参数为true,即使没有收到通知,wait也会返回,此时本线程互斥量已经加锁
(2)如果参数为false,在没有收到通知时,解锁互斥量wait一直阻塞
(3)如果没有参数,与false一样

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

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

相关文章

5-网络初识——封装和分用

目录 1.数据封装的过程 2.数据分用的过程 PS&#xff1a;网络数据传输的基本流程&#xff08;以QQ为例&#xff0c;A给B发送一个hello&#xff09;&#xff1a; 一、发送方&#xff1a; 二、接收方&#xff1a; 不同的协议层对数据包有不同的称谓&#xff0c;在传输层叫做…

Linux:忘记root密码解决办法

如果你是虚拟机只要将光盘镜像连接到虚拟机上&#xff0c;以光盘iso镜像启动 如果你是真机或服务器那将实体u盘或实体光盘连接至设备并且以连接的设备启动 开机时候打断开机 使用 &#xff08;u盘|光盘&#xff09;引导启动 troubleshooting rescue a centos system 输入 1…

前后端分离式项目架构流程(爆肝两万字)

文章目录 &#x1f412;个人主页&#x1f3c5;JavaEE系列专栏&#x1f4d6;前言&#xff1a; 【&#x1f387;前端】先创建Vue-cli项目&#xff0c;请选择此项目【&#x1f380;创建路由】打开命令行工具&#xff0c;进入你的项目目录&#xff0c;输入下面命令。1.创建 router …

SimpleCG绘图函数(4)--绘制圆

在前一篇教程我们利用绘制矩形功能绘制了一个城市,接下来我们讲解另外一个同样重要且基础的图形----圆形。并一起看看该图形能绘制哪些应用呢。 绘制圆形相关函数如下&#xff1a; //圆心坐标(nXCenter,nYCenter),半径为nRatio//绘无填充制圆 void circle( int nXCenter, int …

KG-BERT: BERT for Knowledge Graph Completion 2019ACL

把BERT用在知识图谱补全上 提出KG-BERT模型&#xff0c;在预训练好的BERT基础上继续fine-tuning。 1.传统KGC方法 传统的KGC方法一般依赖于KGE&#xff0c;而KGE往往通过将KG中的三元组关系投影到某个表示空间中&#xff0c;然后使用打分函数对三元组的合理性进行评估&#x…

OA系统流程传出文档

泛微OA如何与第三方接口交互 注意: 1.对于泛微OA中不能作为节点后的自定义编码代码,可能有以下几种原因: 代码存在语法错误:节点后的自定义编码代码应该是正确的Java代码,如果代码中存在语法错误,如缺少分号或者括号不匹配等,将不能正常编译执行。 缺少必要的依赖:节点…

C++ 内存分区模型

C程序在执行时&#xff0c;将内存大方向划分为4个区域 代码区&#xff1a;存放函数体的二进制代码&#xff0c;由操作系统进行管理的 全局区&#xff1a;存放全局变量和静态变量以及常量 栈区&#xff1a;由编译器自动分配释放 , 存放函数的参数值 , 局部变量等 堆区&…

CS5366芯片方案|单芯片type-C转HMID+PD+U3拓展坞方案|CS5366设计电路原理图

CS5366是一款高性能USB Type-c/DisplayPort TM&#xff08;DP&#xff09;到HDMI2.0转换器&#xff0c;设计用于USB Type-c源到HDMI2.0sink。CS5366集成了符合DP1.4标准的接收器和符合hdmi2.0标准的发射器。还包括两个CC控制器用于CC通信&#xff0c;以实现DP Alt Mode和功率传…

目标检测中,DETR方法为何class设置为91+1,DINO中为91

基于DEtection TRansformer的DETR框架https://github.com/facebookresearch/detr因为end-to-end&#xff0c;无需后处理等优点&#xff0c;逐渐得到青睐。DINO方法https://github.com/IDEA-Research/DINO更是取得了在COCO2017的SOTA结果。 其中&#xff0c;在DETR方法中&#…

Revit简单的门族创建及CAD图纸翻模门窗

一、Revit简单的门族创建步骤 门是我们建筑模型中不可缺少的一个构件&#xff0c;如何在族中绘制一个自己的门族呢?下面教大家绘制一个简单的门族&#xff0c;让你了解门的构件绘制。 打开公制门族进行创建 首先我们要进行门框的创建&#xff0c;很多人会以为系统自带的这个是…

【数据结构】一篇文章带你彻底学会《后缀表达式》

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c语言系列专栏&#xff1a;c语言之路重点知识整合 &#x…

什么是项目可交付成果?定义、示例及管理工具

项目产生可交付成果&#xff0c;这只是项目活动的结果。项目可交付成果可大可小&#xff0c;其数量也因项目而异。它们是由项目管理团队和利益相关者在项目规划阶段商定的。 换句话说&#xff0c;任何类型的项目都有投入和产出。投入是你投入到项目中的东西&#xff0c;如数据…

Pixhawk无人机-ArduPilot 软件SITL仿真模拟飞行(SITL+MAVProxy)

1 引言 本人是先看了多个博客实现了&#xff1a;在ubuntu下建立完整的ardupilot开发环境。 该文是基于搭建完编译环境后&#xff0c;也就是搭建好ardupilot的仿真环境实现的。 在文章: 《Pixhawk无人机扩展教程(5)—SITL仿真模拟飞行&#xff1a;开发环境搭建》.中指出&#…

究竟什么是CRM?一文带您了解

目录 一、什么是CRM&#xff1f;它是用来做什么的&#xff1f; 1、获取商机的源头&#xff1a;全渠道营销管理 2、业绩提升的核心&#xff1a;销售管理 3、有温度的触达&#xff1a;客户服务 二、企业为什么需要布局CRM 1、销售是一场没有硝烟的战争 2、信息孤岛存在&am…

调用华为API实现中文语音识别

目录 1. 作者介绍2. 华为云中文语音识别2.1 录音文件识别与获取2.2 限制要求2.3 对象存储服务&#xff08;OBS&#xff09;简介 3. 实验过程以及结果3.1获得API3.2 代码实现3.3 运行结果 参考&#xff08;可供参考的链接和引用文献&#xff09; 1. 作者介绍 张楠&#xff0c;女…

【unity之c#专题篇】——进阶知识实践练习

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

如果你很焦虑、浮躁,不如去读一读林曦这本《无用之美》

生活中不可或缺的是柴米油盐&#xff0c;而濡养人心的往往是无用之美。——林曦    很难用语言写出这本书的美。有些书会给你带来内心的激荡&#xff0c;有些会让你充满力量&#xff0c;而林曦老师的书便自带一种轻盈的美&#xff0c;越往下读越能让人凝神静气。      …

浅谈一下@Async和SpringSecurityContext可能会遇到的问题和解决方案

Async和SpringSecurityContext 场景回溯 在执行一个用时较长的批量插入业务的时候,我尝试使用Async异步对业务进行优化,但是却给我报了空指针的错误,定位之后发现 此处我是基于SpringSecurity来获取用户的 是currentUserService获取到的当前登陆用户为空导致的,但是当前确实是…

文心一言 VS 讯飞星火 VS chatgpt (27)-- 算法导论5.1 2题

二、请描述 RANDOM(a&#xff0c;b)过程的一种实现&#xff0c;它只调用 RANDOM(0&#xff0c;1)。作为a和b的函数&#xff0c;你的过程的期望运行时间是多少? 文心一言&#xff1a; 假设我们有一个伪随机数生成器&#xff0c;可以生成在[0,1)范围内的随机数。那么我们可以使…

深入探讨JMeter中不为人知的JSONPath用法

在jmeter使用过程中&#xff0c;我们经常会看到接口返回数据类型为application/json&#xff0c;也就时我们常说的json格式。 而在功能测试时&#xff0c;我们经常会要对它的结果进行断言&#xff0c;确认结果是否与预期一致&#xff0c;有时候还会想从结果中提取某个值&#…