本文用简单的程序模拟了死锁的形成。死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象。
#include<iostream>
#include<thread>
#include<mutex>
#include<list>
using namespace std;
//保证两个互斥量,加锁的顺序相同
class MsgManage
{
public:
MsgManage() {}
~MsgManage() {}
void InMsg()
{
for (int i = 0; i < 10000; i++)
{
cout << "插入元素: " << i << endl;
myMutex1.lock(); //先锁定1,再锁定2
myMutex2.lock();
myList.push_back(i);
myMutex2.unlock();
myMutex1.unlock();
}
}
bool outMsgProc(int &num)
{
myMutex2.lock(); //先锁定2,再锁定1
myMutex1.lock();
if (!myList.empty())
{
num = myList.front();
myList.pop_front();
myMutex1.unlock();
myMutex2.unlock();
return true;
}
myMutex1.unlock();
myMutex2.unlock();
return false;
}
void OutMsg()
{
for (int i = 0; i < 10000; i++)
{
int num;
bool result = outMsgProc(num);
if (result)
{
cout << "移除元素: " << num << endl;
}
else
{
cout << "消息队列为空" << endl;
}
}
}
private:
list<int> myList;
mutex myMutex1;
mutex myMutex2;
};
int main()
{
MsgManage manage;
thread outMsg(&MsgManage::OutMsg, &manage);
thread inMsg(&MsgManage::InMsg, &manage);
inMsg.join();
outMsg.join();
return 0;
}
程序运行结果(出现了死锁现象):
避免死锁的一个简单方法是:所以线程按照固定的顺序访问资源。即:函数InMsg()中先锁定myMutex1,后锁定myMutex2。函数outMsgProc()中也应该先锁定myMutex1,后锁定myMutex2。
outMsgProc()调整后的代码如下(不再出现死锁现象):
bool outMsgProc(int &num)
{
myMutex1.lock(); //先锁定1,再锁定2
myMutex2.lock();
if (!myList.empty())
{
num = myList.front();
myList.pop_front();
myMutex1.unlock();
myMutex2.unlock();
return true;
}
myMutex1.unlock();
myMutex2.unlock();
return false;
}