c++多线程系列
c++多线程thread操作(五)unique_lock加锁
c++多线程thread操作(七)父进程获取子进程变量的结果
(终)c++多线程thread操作(十)多线程并行实现数据相加的和
1. 死锁问题的出现,出现了循环调用,并且抢占了资源。
class LofFile {
private:
mutex m_mutex1;
mutex m_mutex2;
public:
LofFile() {}
void shared_print(string msg, int id) {
lock_guard<mutex> guard1(m_mutex1);
lock_guard<mutex> guard2(m_mutex2);
cout << "--1--From" << id << " : " << msg << endl;
}
void shared_print2(string msg, int id) {
lock_guard<mutex> guard2(m_mutex2);
lock_guard<mutex> guard1(m_mutex1);
cout << "--2--From" << id << " : " << msg << endl;
}
};
void func_1(LofFile&log) { //配合3
for (int i = 0; i > -100; i--) { //写1000就顺序执行,写100就死锁
log.shared_print("From t1: ", i); // cout是可竞争资源
}
}
int main() {
LofFile log;
thread t1(func_1,ref(log));
for (int i = 0; i < 100; i++) {
log.shared_print2("From main: ", i);
}
t1.join();
return 0;
}
上述代码shared_print锁住mutex1,shared_print锁住mutex2,二者不释放自己锁的情况下请求访问其它资源;
2. 解决方案:
(1)手动将shared_print2中guard_lock锁的顺序定义为和1一样:
void shared_print2(string msg, int id) {
lock_guard<mutex> guard2(m_mutex1); // 交换2者顺序
lock_guard<mutex> guard1(m_mutex2);
cout << "--2--From" << id << " : " << msg << endl;
}
(2)利用库函数自动设定顺序:
void shared_print(string msg, int id) {
//2. Lock固定顺序,需要在guard后面添加adopt_lock
lock(m_mutex1, m_mutex2);
lock_guard<mutex> guard1(m_mutex1,adopt_lock);
lock_guard<mutex> guard2(m_mutex2, adopt_lock);
cout << "--1--From" << id << " : " << msg << endl;
}
void shared_print2(string msg, int id) {
lock(m_mutex1, m_mutex2);
lock_guard<mutex> guard2(m_mutex2, adopt_lock);
lock_guard<mutex> guard1(m_mutex1, adopt_lock);
cout << "--2--From" << id << " : " << msg << endl;
}
lock 函数可以指定锁的顺序,需要在lock_guard下添加adopt_lock形参;