死锁产生
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <fstream>
class LofFile{
public:
LofFile();
~LofFile();
void share_print(std::string id, int value);
void share_print2(std::string id, int value);
private:
std::mutex m_mutex;
std::mutex m_mutex2;
std::ofstream f;//f是被mutex所保护的资源
};
LofFile::LofFile(){
f.open("log.txt");
}
LofFile::~LofFile(){
}
void LofFile::share_print(std::string id, int value){
std::lock_guard<std::mutex> locker(m_mutex);
std::lock_guard<std::mutex> locker2(m_mutex2);
std::cout << "from" << id << ":" << value << std::endl;
}
void LofFile::share_print2(std::string id, int value) {
std::lock_guard<std::mutex> locker2(m_mutex2);
std::lock_guard<std::mutex> locker(m_mutex);
std::cout << "from" << id << ":" << value << std::endl;
}
void function_1(LofFile& log) {
for (int i = 0; i > -100; i--)
log.share_print("From function_1", i);
}
int main() {
LofFile log;
std::thread t1(function_1,std::ref(log));
for (int i = 0; i > -100; i--)
log.share_print2("From main", i);
t1.join();
return 0;
}
- 当function_1线程锁住m_mutex
- main线程锁住m_mutex2
- function_1等待m_mutex2解锁
- main等待m_mutex解锁
- 导致死锁
死锁避免
- 评估是否需要两个以上的锁
- 避免调用mutex的同时调用其他的不熟悉的函数,有可能这个函数包含了其它的另外的锁
- 使用C++标准库提供的lock函数,可以确保多个mutex的顺序是相同的(部分极端场合,lock函数不能使用)
方法1:确保每一个locker顺序相同
方法2:C++提供机制
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <fstream>
class LofFile{
public:
LofFile();
~LofFile();
void share_print(std::string id, int value);
void share_print2(std::string id, int value);
private:
std::mutex m_mutex;
std::mutex m_mutex2;
std::ofstream f;//f是被mutex所保护的资源
};
LofFile::LofFile(){
f.open("log.txt");
}
LofFile::~LofFile(){
}
void LofFile::share_print(std::string id, int value){
//按顺序上锁
std::lock(m_mutex, m_mutex2);
//locker获取mutex的所有权,析构时解锁mutex
std::lock_guard<std::mutex> locker(m_mutex,std::adopt_lock);
std::lock_guard<std::mutex> locker2(m_mutex2, std::adopt_lock);
std::cout << "from" << id << ":" << value << std::endl;
}
void LofFile::share_print2(std::string id, int value) {
//按顺序上锁
std::lock(m_mutex, m_mutex2);
//locker获取mutex的所有权,析构时解锁mutex
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;
}
void function_1(LofFile& log) {
for (int i = 0; i > -100; i--)
log.share_print("From function_1", i);
}
int main() {
LofFile log;
std::thread t1(function_1,std::ref(log));
for (int i = 0; i > -100; i--)
log.share_print2("From main", i);
t1.join();
return 0;
}