死锁

简介: 死锁

死锁的最常见情况


相互等待。 


业务说明


对于简单的业务,可以规定一次只能锁定一个单元,但对于复杂业务,这种方法不可行。比如:金银互换,1金换10银。分4步:1,判断金币足够。 2,判断银币没到上限 3,金币减少。 4,银币增加。假定只有一金币,线程一执行步骤一,发现金币足够,碰巧线程被挂起; 线程二执行执行步骤一,发现金币足够。于是金币变成了-1。为了避免这种情况,必须同时锁金银。函数一,先锁金,再锁银;函数二,先锁银,再锁金。可能出现如下情况:线程一,锁了金,想锁银;线程二,锁了银,想锁金。


测试代码


namespace TEST1
{
class CTestDeadLock
{
public:
static UINT Test1(LPVOID)
{// 模拟一金币换10银币
s_lock1.Lock();
Sleep(1);
s_lock2.Lock();
if ( ( s_iJin > 0) && (s_iYin < 1000 ) )
{
s_iJin--;
s_iYin += 10;
}
s_lock1.UnLock();
s_lock2.UnLock();
return 0;
}
static UINT Test2(LPVOID)
{
s_lock2.Lock();
Sleep(1);
s_lock1.Lock();
if ((s_iYin > 10) && (s_iJin < 1000))
{
s_iYin-= 10;
s_iJin++;
}
s_lock2.UnLock();
s_lock1.UnLock();
return 0;
}
protected:
static SNMFC::CriticalReadWriteLock s_lock1;
static SNMFC::CriticalReadWriteLock s_lock2;
static int s_iJin;
static int s_iYin;
};
SNMFC::CriticalReadWriteLock CTestDeadLock::s_lock1;
SNMFC::CriticalReadWriteLock CTestDeadLock::s_lock2;
int CTestDeadLock::s_iJin =0;
int CTestDeadLock::s_iYin = 0;
}
void CSNMFCDlg::OnBnClickedButton22()
{
AfxBeginThread(TEST1::CTestDeadLock::Test1, NULL);
TEST1::CTestDeadLock::Test2(NULL);
}


解决方法


上面的Sleep(1)是为了模拟碰巧被挂起。解决死锁的方法:按特定的顺序锁。如果要锁的单元多,调用者根本无法知道,先锁那个。


锁管理类


先设置标志,Lock的时候自动按顺序锁。


namespace TEST2
{
//每个线程都自动分配锁
class IRWLocks : public SN::IReadWriteLock
{
public:
virtual bool HasLock() = 0;
virtual bool HasLockRead() = 0;
};
//为每个线程都生产一把锁
class CCriticalRWLocks : public IRWLocks
{
protected:
class CLockInfo : public SNMFC::CriticalReadWriteLock
{
public:
CLockInfo()
{
m_iLockNum = 0;
m_iLockReadNum = 0;
}
virtual void Lock() override
{
SNMFC::CriticalReadWriteLock::Lock();
m_iLockNum++;
}
virtual void UnLock() override
{
m_iLockNum--;
SNMFC::CriticalReadWriteLock::UnLock();
}
virtual void LockRead() override
{
m_iLockReadNum++;
SNMFC::CriticalReadWriteLock::LockRead();
}
virtual void UnLockRead() override
{
m_iLockReadNum--;
SNMFC::CriticalReadWriteLock::UnLockRead();
}
bool HasLock()const
{
return m_iLockNum > 0;
}
bool HasLockRead()const
{
return m_iLockReadNum > 0;
}
protected:
int m_iLockNum ;
int m_iLockReadNum ;
};
public:
CCriticalRWLocks()
{
Init();
}
virtual void Lock() override
{
GetLockByCurrentThreadID()->Lock();
}
virtual void UnLock() override
{
GetLockByCurrentThreadID()->UnLock();
}
virtual void LockRead() override
{
GetLockByCurrentThreadID()->LockRead();
}
virtual void UnLockRead() override
{
GetLockByCurrentThreadID()->UnLockRead();
}
bool HasLock() override
{
return GetLockByCurrentThreadID()->HasLock();
}
bool HasLockRead() override
{
return GetLockByCurrentThreadID()->HasLockRead();
}
protected:
CLockInfo* GetLockByCurrentThreadID()
{
SN::CLockHlp lock(m_lock);
DWORD dThreadID = ::GetCurrentThreadId();
if (m_mLocks.end() == m_mLocks.find(dThreadID))
{
m_mLocks[dThreadID] = new CLockInfo();
}
return m_mLocks[dThreadID] ;
}
virtual void Init()
{
m_lock.Init();
}
std::map<int, CLockInfo*> m_mLocks;
SNMFC::CCriticalSection m_lock;
};
template<class DATA>
class CLockUnit
{
public:
DATA* GetData()
{
if (!m_locks.HasLock())
{
return NULL;
}
return &m_data;
}
const DATA* GetConstData()
{
if (!m_locks.HasLockRead())
{
return NULL;
}
return &m_data;
}
CCriticalRWLocks m_locks;
private:
DATA m_data;
};
//确保以某种顺序,加锁,解锁 以防止死锁
class CLockUnitManage
{
public:
CLockUnitManage()
{
m_bHasLock = FALSE;
}
void SetLockFlag(SN::IReadWriteLock& lock)
{
if (m_bHasLock)
{
return;
}
m_mLocks[&lock] = 2;
}
void SetLockReadFlag(SN::IReadWriteLock& lock)
{
if (m_bHasLock)
{
return;
}
m_mLocks[&lock] = 1;
}
void BeginLock()
{
if (m_bHasLock)
{
return;
}
m_bHasLock = TRUE;
for (std::map<SN::IReadWriteLock*, int>::const_iterator it = m_mLocks.begin(); it != m_mLocks.end(); ++it)
{
if (2 == it->second)
{
it->first->Lock();
}
else if (1 == it->second)
{
it->first->LockRead();
}
}
}
void EndLock()
{
if (!m_bHasLock)
{
return;
}
m_bHasLock = FALSE;
for (std::map<SN::IReadWriteLock*, int>::const_iterator it = m_mLocks.begin(); it != m_mLocks.end(); ++it)
{
if (2 == it->second)
{
it->first->UnLock();
}
else if (1 == it->second)
{
it->first->UnLockRead();
}
}
}
~CLockUnitManage()
{
EndLock();
}
protected:
std::map<SN::IReadWriteLock*,int> m_mLocks;
bool m_bHasLock;//锁定状态下,解锁前无法 ,增加标志和锁。
};
CLockUnit<CString> g_strName;
CLockUnit<int> g_iAge;
class CTestDeadLock
{
public:
static UINT Test1(LPVOID)
{
CLockUnitManage lockManages;
lockManages.SetLockFlag(g_strName.m_locks);
lockManages.SetLockFlag(g_iAge.m_locks);
lockManages.BeginLock();
CString* pStr = g_strName.GetData();
int* pI = g_iAge.GetData();
*pStr += _T("A");
*pI += 1;
Sleep(1);
return 0;
}
static UINT Test2(LPVOID)
{
CLockUnitManage lockManages;
lockManages.SetLockFlag(g_iAge.m_locks);
lockManages.SetLockFlag(g_strName.m_locks);
lockManages.BeginLock();
CString* pStr = g_strName.GetData();
int* pI = g_iAge.GetData();
*pStr += _T("A");
*pI += 1;
Sleep(1);
return 0;
}
};
}
void CSNMFCDlg::OnBnClickedButton23()
{
for (int i = 0; i < 100; i++)
{
AfxBeginThread(TEST2::CTestDeadLock::Test1,NULL);
AfxBeginThread(TEST2::CTestDeadLock::Test2, NULL);
}
TEST2::CTestDeadLock::Test2(NULL);
}
相关文章
|
安全 物联网 网络安全
什么是等保(信息安全等级保护)?
“等保”,即信息安全等级保护,是我国网络安全领域的基本国策、基本制度。早在2017年8月,公安部评估中心就根据网信办和信安标委的意见将等级保护在编的5个基本要求分册标准进行了合并形成《信息安全技术 网络安全等级保护基本要求》一个标准。(GB/T 22239—2019代替 GB/T 22239-2008)该标准于2019年5月10日发布,于2019年12月1日开始实施。
14117 1
什么是等保(信息安全等级保护)?
|
缓存 NoSQL Redis
Redis中的事件驱动框架(二)
Redis中的事件驱动框架
234 0
|
6天前
|
云安全 人工智能 安全
AI被攻击怎么办?
阿里云提供 AI 全栈安全能力,其中对网络攻击的主动识别、智能阻断与快速响应构成其核心防线,依托原生安全防护为客户筑牢免疫屏障。
|
15天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
10天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
618 216
|
存储 人工智能 监控
从代码生成到自主决策:打造一个Coding驱动的“自我编程”Agent
本文介绍了一种基于LLM的“自我编程”Agent系统,通过代码驱动实现复杂逻辑。该Agent以Python为执行引擎,结合Py4j实现Java与Python交互,支持多工具调用、记忆分层与上下文工程,具备感知、认知、表达、自我评估等能力模块,目标是打造可进化的“1.5线”智能助手。
859 61
|
8天前
|
人工智能 移动开发 自然语言处理
2025最新HTML静态网页制作工具推荐:10款免费在线生成器小白也能5分钟上手
晓猛团队精选2025年10款真正免费、无需编程的在线HTML建站工具,涵盖AI生成、拖拽编辑、设计稿转代码等多种类型,均支持浏览器直接使用、快速出图与文件导出,特别适合零基础用户快速搭建个人网站、落地页或企业官网。
1307 157
|
5天前
|
编解码 Linux 数据安全/隐私保护
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
246 138