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参数