多线程死锁的产生和解决
来源:互联网 发布:java web 日志 编辑:程序博客网 时间:2024/06/06 09:01
什么是死锁
线程死锁一般是发生在多个线程的多个锁之间,比如线程A拥有临界区对象LockA的所有权,等待临界区对象LockB;线程B拥有临界区对象LockB的所有权,等待临界区对象LockA;由于两个线程间相互等待各自的锁,并且不释放,就会导致程序一直等待下去,发生死锁;
死锁伪代码
//线程AEnterCriticalSection(&g_csLockA);Sleep(10);EnterCriticalSection(&g_csLockB);//等B....//对于释放顺序没有影响LeaveCriticalSection(&g_csLockA);LeaveCriticalSection(&g_csLockB);
//线程BEnterCriticalSection(&g_csLockB);Sleep(10);EnterCriticalSection(&g_csLockA);//等A....//对于释放顺序没有影响LeaveCriticalSection(&g_csLockA);LeaveCriticalSection(&g_csLockB);
过分分析
比如线程A先获得时间片,线程A执行并获得LockA的所有权;sleep(10)之后,线程B获得时间片,线程B执行并获得LockB的所有权;
当线程A再次活动执行权,线程A会等待LockB的的所有权,同理线程B也还会等LockB的所有权;由于两者都不释放,程序会一致等待下去,发生了死锁;
解决死锁
在多线程编程中,为了避免发生这样的情况,可以有两种方法进行预防,这样可以避免死锁的发生;
- 加锁顺序一致
//线程A:先等锁A,再等锁BEnterCriticalSection(&g_csLockA);Sleep(10);EnterCriticalSection(&g_csLockB);....//对于释放顺序没有影响LeaveCriticalSection(&g_csLockA);LeaveCriticalSection(&g_csLockB);//线程B:也是先等锁A,再等锁BEnterCriticalSection(&g_csLockA);Sleep(10);EnterCriticalSection(&g_csLockB);....//对于释放顺序没有影响LeaveCriticalSection(&g_csLockA);LeaveCriticalSection(&g_csLockB);
- 避免锁未释放的场景
//线程:EnterCriticalSection(&g_csLockA);Sleep(10);EnterCriticalSection(&g_csLockB);....//对于释放顺序没有影响LeaveCriticalSection(&g_csLockA);....return true;.....LeaveCriticalSection(&g_csLockB);
死锁实例
// MultiThread.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"//#include <windows.h>#include <iostream>#include <afxmt.h>using namespace std;int g_nIndex = 0;const int nMaxCnt = 20;CRITICAL_SECTION g_csLockA;CRITICAL_SECTION g_csLockB;DWORD WINAPI Thread1SynByCS(LPVOID lpParameter){ while (TRUE) { //先等锁A,再等锁B,发生死锁,程序一直等待,直至主线程结束 EnterCriticalSection(&g_csLockA); Sleep(10); EnterCriticalSection(&g_csLockB); //关键代码段-begin if (g_nIndex++ < nMaxCnt) { cout << "Index = "<< g_nIndex << " "; cout << "Thread2 is runing" << endl; //权限释放 LeaveCriticalSection(&g_csLockA); LeaveCriticalSection(&g_csLockB); } else { //权限释放 LeaveCriticalSection(&g_csLockA); LeaveCriticalSection(&g_csLockB); //关键代码段-end break; } } return 0;}DWORD WINAPI Thread2SynByCS(LPVOID lpParameter){ while (TRUE) { //先等锁B,再等锁A,发生死锁,程序一直等待,直至主线程结束 EnterCriticalSection(&g_csLockB); Sleep(10); EnterCriticalSection(&g_csLockA); //关键代码段-begin if (g_nIndex++ < nMaxCnt) { cout << "Index = "<< g_nIndex << " "; cout << "Thread2 is runing" << endl; //权限释放 LeaveCriticalSection(&g_csLockA); LeaveCriticalSection(&g_csLockB); } else { //权限释放 LeaveCriticalSection(&g_csLockA); LeaveCriticalSection(&g_csLockB); //关键代码段-end break; } } return 0;}int _tmain(int argc, _TCHAR* argv[]){ HANDLE hThread1 = NULL; HANDLE hThread2 = NULL; //初始化关键代码段对象 InitializeCriticalSection(&g_csLockA); InitializeCriticalSection(&g_csLockB); //创建新的线程 hThread1 = CreateThread(NULL,0,Thread1SynByCS,NULL,0,NULL);//立即执行 hThread2 = CreateThread(NULL,0,Thread2SynByCS,NULL,0,NULL);//立即执行 //无须对新线程设置优先级等操作,关闭之 //良好的编码习惯 CloseHandle(hThread1); CloseHandle(hThread2); Sleep(3000); //删掉关键代码段对象,并删除系统资源 DeleteCriticalSection(&g_csLockA); DeleteCriticalSection(&g_csLockB); return 0;}
0 0
- 多线程死锁的产生和解决
- 死锁的产生和解决
- 死锁的产生和解决
- 死锁产生和解决
- 死锁,死锁产生的原因,产生死锁的必要条件和解决死锁的方法
- JAVA 死锁,死锁产生的原因,产生死锁的必要条件和解决死锁的方法
- 死锁产生的原因和解决
- 产生死锁的原因和必要条件 解决死锁的方法
- 死锁产生的条件和解决死锁的方法
- Java多线程-死锁的出现和解决
- Java多线程产生死锁的原因和解决方法
- 多线程——死锁产生的条件和过程分析
- 死锁的产生与解决
- 死锁的产生与解决
- 多线程四,死锁产生的原因和死锁的例子(毕向东老师)
- 死锁的产生和预防死锁
- 产生死锁的原因和必要条件+解决死锁的基本方法
- 产生死锁的原因和必要条件+解决死锁的基本方法
- 静态字段
- 用python统计文件中各个单词出现的次数
- 高软实验
- 数据库批量备份
- Linux网络编程[网络中的广播]
- 多线程死锁的产生和解决
- cmake 常见问题及解决
- 笔记本怎么设置WIfi热点
- BGAQRCode-Android
- 数据库批量还原
- Java编程思想-15泛型
- NUC1397 Oil Deposits【DFS】
- libsvm——参数优化工具grid.py的使用
- 算法竞赛入门经典(第2版)习题3-5 谜题(Puzzle) Uva227