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

 更新时间:2023年06月06日 15:00:47   作者:hsy12342611  
这篇文章主要介绍了C++11中条件标量和互斥锁应用出现死锁思考,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

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

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一样

到此这篇关于C++11中条件标量和互斥锁应用出现死锁思考的文章就介绍到这了,更多相关C++11条件标量和互斥锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用C++实现工资管理中的随机教师信息生成功能

    使用C++实现工资管理中的随机教师信息生成功能

    这篇文章主要介绍了使用C++实现工资管理中的随机教师信息生成功能,想要做一个教师工资管理系统,就必须得准备好数据,但是这些数据如果用手一行一行地敲,那么工作量是非常大的,因此,我就产生了用C语言实现直接生成大量的教师基本信息的想法,需要的朋友可以参考下
    2023-05-05
  • 详解C语言和Python中的线程混用

    详解C语言和Python中的线程混用

    这篇文章主要介绍了C和Python中的线程混用的相关资料,文中讲解非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • C语言数据结构与算法之队列的实现详解

    C语言数据结构与算法之队列的实现详解

    队列只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)的原则。本文将通过实例详细说说队列的实现,需要的可以学习一下
    2022-10-10
  • C语言复杂链表的复制实例详解

    C语言复杂链表的复制实例详解

    这篇文章主要为大家详细介绍了C语言复杂链表的复制,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • C语言数据类型和格式说明符基础教程示例

    C语言数据类型和格式说明符基础教程示例

    这篇文章主要为大家介绍了C语言数据类型和格式说明符基础教程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • C++语言pow函数的具体使用

    C++语言pow函数的具体使用

    本文主要介绍了C++语言pow函数的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • 利用c++写一个简单的推箱子小游戏

    利用c++写一个简单的推箱子小游戏

    推箱子想必是很多人童年时期的经典游戏,我们依旧能记得抱个老人机娱乐的场景,下面这篇文章主要给大家介绍了关于如何利用c++写一个简单的推箱子小游戏的相关资料,需要的朋友可以参考下
    2021-09-09
  • Effective C++ 学习笔记

    Effective C++ 学习笔记

    这篇文章主要介绍了Effective C++ 学习笔记,想学习Effective C++的朋友可以参考一下
    2023-08-08
  • C++核心编程之占位参数和默认参数

    C++核心编程之占位参数和默认参数

    这篇文章主要介绍了C++核心编程之占位参数和默认参数,c++中函数的形参列表中的形参是可以有默认值的,函数的形参列表里可以有占位参数,用来占位,调用函数时必须填补位置。下面更多相关内容的详细介绍,需要的小伙伴可以参考一下
    2022-03-03
  • 简明的C++函数指针学习教程

    简明的C++函数指针学习教程

    这篇文章主要介绍了C++函数指针的学习教程,讲到了函数指针的定义及把指针作为函数参数进行传递的用法,需要的朋友可以参考下
    2016-04-04

最新评论