C++中使用mutex带来的死锁

c++多线程中死锁多出现在使用多个mutex,而mutex的顺序不一样。比如下面的代码为了保证输出的原子性,在两个输出的函数中使用了两个mutex
但是这两个mutex锁的顺序是不一样的,结果就造成了死锁。

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

class LofFile
{
public:

	void share_print(std::string msg, int id) {
		std::lock_guard<std::mutex> guard(m_mutex);
		std::lock_guard<std::mutex> guard2(m_mutex2);
		std::cout << msg << " " << id << std::endl;
	}

	void share_print_f(std::string msg, int id) {
		std::lock_guard<std::mutex> guard(m_mutex2);
		std::lock_guard<std::mutex> guard2(m_mutex);
		std::cout << msg << " " << id << std::endl;
	}
private:
	std::mutex m_mutex;
	std::mutex m_mutex2;
};

void fun1(LofFile& log)
{
	for (int i = 0; i < 50; i++)
	{
		log.share_print("fun1 id", i);
	}
}

int main(int argc, char** argv)
{
	LofFile log;
	std::thread t1(fun1, std::ref(log));
	for (int i = 0; i < 50; i++)
	{
		log.share_print_f("main id", i);
	}
	if (t1.joinable()) {
		t1.join();
	}
	return 0;
}

如何避免在C++中使用mutex出现死锁

1、判断自己的代码是否需要多个mutex
2、清楚了解自己调用的方法之类的是否也有使用mutex的情况
3、使用标准库中的std::Lock(std::mutex,···)来设置mutex

如何使用std::Lock(std::mutex,···)

class LofFile
{
public:

	void share_print(std::string msg, int id) {
		std::lock(m_mutex, m_mutex2);
		std::lock_guard<std::mutex> guard(m_mutex,std::adopt_lock);
		std::lock_guard<std::mutex> guard2(m_mutex2,std::adopt_lock);
		std::cout << msg << " " << id << std::endl;
	}

	void share_print_f(std::string msg, int id) {
		std::lock(m_mutex, m_mutex2);
		std::lock_guard<std::mutex> guard(m_mutex2,std::adopt_lock);
		std::lock_guard<std::mutex> guard2(m_mutex,std::adopt_lock);
		std::cout << msg << " " << id << std::endl;
	}
private:
	std::mutex m_mutex;
	std::mutex m_mutex2;
};

主要修改了两个地方
调用std::lock_guardstd::mutex 前先使用std::lock(std::mutex,···),
其次在std::lock_guardstd::mutex 中加入std::adopt_lock参数

posted @ 2020-08-02 15:48  cyssmile  阅读(1227)  评论(0编辑  收藏  举报