如何处理死锁问题

本文总结了处理死锁的三个关键点:评估是否确实需要多个mutex,避免锁住mutex时调用未知函数,以及使用std::lock确保mutex获取的顺序,以防止死锁的发生。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码来源于百度传课:htps://chuanke.baidu.com/v3891329-172880-852300.html

总结如下:

1.评估一下程序,看看是否确实需要有两个mutex?如果只有一个mutex,就不存在死锁的问题了。

2.避免在锁住mutex的同时,去调用另外的我们不熟悉的函数,因为有可能这个函数包含了另外的锁,所以我们必须清楚我们所调用的其他的函数或者类。

3.如果确实需要在同一时间使用两个以上的mutex,那么可以使用c++标准库提供的std::lock函数,这样就可以确保mutex的顺序是相同的。在某些极端的情况下可能没法使用std::lock函数,这时候就要确保锁的先后顺序是一致的(如例子中,我们应该确保locker和locker2在两个函数shared_print和shared_print2中出现的先后顺序是一致的)。

 

#include <iostream>
#include <thread>
#include <mutex>
#include <string>
#include <fstream>

//std::mutex mu;
//
//void shared_print(std::string msg, int id)
//{
//	//mu.lock();//若不释放则资源会被一直占用
//	std::cout << msg << id << std::endl;//相当于对cout这个资源加锁,若此句出现了异常则资源将会被一直占用
//	//mu.unlock();
//}

class LogFile
{
public:
	LogFile()
	{
		f.open("log.txt");
	}
	
	void shared_print(std::string id, int value)
	{
		std::lock(m_mutex, m_mutex2);
		std::lock_guard<std::mutex> locker(m_mutex,std::adopt_lock);//第二个参数的意思是,该mutex已经被锁住。获取mutex所有权,析构时解锁mutex
		std::lock_guard<std::mutex> locker2(m_mutex2, std::adopt_lock);
		std::cout << "From" << id << ":" << value << std::endl;//std::cout和f是一样的,只是为了更方便地查看结果,不用输出流f,而用cout
	}
	void shared_print2(std::string id, int value)
	{
		std::lock(m_mutex, m_mutex2);
		std::lock_guard<std::mutex> locker2(m_mutex2, std::adopt_lock);
		std::lock_guard<std::mutex> locker(m_mutex,std::adopt_lock);
		std::cout << "From" << id << ":" << value << std::endl;
	}
	
protected:
private:
	std::mutex m_mutex;
	std::mutex m_mutex2;
	std::ofstream f;//资源f是类的成员,也就是说在类的保护之下。这样的话要想用资源必须要用类,这样就起到了资源和锁绑定到一起的作用

};

void Function1(LogFile& log)
{
	for (int i = 0;i < 100;i++)
		log.shared_print("In Funtion1", i);
}

int main()
{
	LogFile log;
	std::thread t1(Function1,std::ref(log));
	for (int j = 0;j < 100;j++)
	{
		log.shared_print2( "In Main" ,j);
	}
	t1.join();
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值