一. 测试代码

#include <windows.h>
#include <tchar.h>
#include <process.h> HANDLE hMutexA = NULL;
HANDLE hMutexB = NULL; unsigned __stdcall ThreadProc1(void * pArg) {
WaitForSingleObject(hMutexA, INFINITE);
Sleep(500);
WaitForSingleObject(hMutexB, INFINITE); printf("+++\n"); ReleaseMutex(hMutexB);
ReleaseMutex(hMutexA); return 0;
} unsigned __stdcall ThreadProc2(void * pArg) {
WaitForSingleObject(hMutexB, INFINITE);
Sleep(500);
WaitForSingleObject(hMutexA, INFINITE); printf("...\n"); ReleaseMutex(hMutexA);
ReleaseMutex(hMutexB); return 0;
} int main()
{
hMutexA = CreateMutex(NULL, FALSE, TEXT("MutexA"));
hMutexB = CreateMutex(NULL, FALSE, TEXT("MutexB")); // 启动线程
HANDLE hThread1 = (HANDLE)_beginthreadex(NULL, 0, ThreadProc1, NULL, 0, NULL);
HANDLE hThread2 = (HANDLE)_beginthreadex(NULL, 0, ThreadProc2, NULL, 0, NULL); getchar(); // 等待线程退出并关闭句柄
if (hThread1) {
WaitForSingleObject(hThread1, INFINITE);
CloseHandle(hThread1);
} if (hThread2) {
WaitForSingleObject(hThread2, INFINITE);
CloseHandle(hThread2);
} // 关闭句柄
if(hMutexA)
CloseHandle(hMutexA);
if(hMutexB)
CloseHandle(hMutexB); return 0;
}

二. 死锁原理

程序生成了2个线程(线程1、线程2)和2个互斥体MutexA和MutexB。

观察线程执行代码可知,这是一个典型的死锁用例,2个线程相互等待。

线程1: 拥有MutexA --> 过一段时间(sleep) ---> 想拥有MutexB

线程2: 拥有MutexB --> 过一段时间(sleep) ---> 想拥有MutexA

线程1想拥有属于线程2的MutexB,而线程2却想拥有属于线程1的MutexA,互不松手,就只能都等着了。

三. 上调试器

~*kvn 查看所有线程调用堆栈:

从线程#1栈帧03可以看到其正在等待句柄00000038。

从线程#2栈帧03可以看到其正在等待句柄00000034。

即:

线程#1(ID:22f4)--->等待句柄38

线程#2(ID:33bc)---> 等待句柄34

到底句柄00000034和00000038是什么类型的,可以使用!handle命令查看:

从图中可以看到:

句柄00000034为名为MutexA的互斥体,被线程ID:2264 拥有。

句柄00000038为名为MutexB的互斥体,被线程ID:33bc 拥有。

即:

线程#1(ID:22f4)等待00000038(互斥体MutexA ),拥有00000034(互斥体MutexB)

线程#2(ID:33bc)等待句柄00000034(互斥体MutexB ),拥有00000038(互斥体MutexA)

所以,爱就是放手,有时候放手会让彼此过得更好。

Windbg调试互斥体(Mutex)死锁的更多相关文章

  1. Linux系统中的信号量(semphore)与互斥体(mutex)

    http://www.embexperts.com/viewthread.php?tid=31 两者最大区别:信号量可以允许多个线程进入临界区,而互斥体只允许一个线程进入临界区.本贴将描述信号量与互斥 ...

  2. C#互斥体——Mutex

    Mutex对象是一个同步基元,可以用来做线程间的同步. 若多个线程需要共享一个资源,可以在这些线程中使用Mutex同步基元.当某一个线程占用Mutex对象时,其他也需要占用Mutex的线程将处于挂起状 ...

  3. [原]调试实战——使用windbg调试TerminateThread导致的死锁

    原调试debugwindbg死锁deadlock 前言 项目里的一个升级程序偶尔会死锁,查看dump后发现是死在了ShellExecuteExW里.经验少,不知道为什么,于是在高端调试论坛里发帖求助, ...

  4. [原]调试实战——使用windbg调试excel启动时死锁

    原调试debugwindbg死锁deadlock 前言 这是几年前在项目中遇到的一个死锁问题,在博客园发布过.我对之前的笔记进行了整理重新发布于此. 本文假设小伙伴们知道一些基本概念,比如什么是.du ...

  5. Windbg调试关键区(CriticalSection)死锁

    一. 准备工作 这里一个有关键区锁死问题的程序,运行之后依次点击"CS锁死"按钮.右上角退出按钮,程序就会卡死.(图1) 对于眼下的这个问题,界面完全失去响应,这说明负责消息处理的 ...

  6. windows系统调用 互斥体mutex

    #include "iostream" #include "windows.h" using namespace std; class CCountUpDown ...

  7. 41、Thead线程 System.Thread与互斥体Mutex

    Thead线程 System.Thread 使用Thread类可以创建和控制线程.下面的代码是创建和启动一个新线程的简单例子.Thread 类的构造函数重载为接受ThreadStart和Paramet ...

  8. 互斥体与互锁 <第五篇>

    互斥体实现了“互相排斥”(mutual exclusion)同步的简单形式(所以名为互斥体(mutex)).互斥体禁止多个线程同时进入受保护的代码“临界区”.因此,在任意时刻,只有一个线程被允许进入这 ...

  9. 转载 互斥体与互锁 <第五篇>

    互斥体实现了“互相排斥”(mutual exclusion)同步的简单形式(所以名为互斥体(mutex)).互斥体禁止多个线程同时进入受保护的代码“临界区”.因此,在任意时刻,只有一个线程被允许进入这 ...

随机推荐

  1. 关于EasyUI中DataGrid控件的一些使用方法总结

    一,DataGrid         控件的工作流程 1,通过JavaScript将一个空白的div美化成一个空白的Datagrid模板 2,Datagrid模板通过制定的Url发送请求,获取数据   ...

  2. 花了一年时间开发出来的EZNest 自动套料软件

    随着国内钢结构制造业的迅猛发展,市场竞争也愈演愈烈.近来钢材价格的大幅攀升,节约用材已成为企制胜的戈键,提高钢材的利用车自然就成了目前许多企业十分关心的一件事.对十大型钢结构生产制造商来说,如留在传统 ...

  3. 【css】主要的块状元素(block element)和内联元素(inline element行内元素)

      内联元素:只在行内发生作用,设置宽高不起作用,不会影响文字内容,使其换行等.竖直方向和间距也不起作用   display可以强制转换行内元素和块状元素,还可以取消显示none   块元素(bloc ...

  4. 网站相关人员信息记录humans.txt

    前面的话 robots.txt文件告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取.而humans.txt文件则是为人类准备的,包含参加该网页设计和建立的相关人员的信息.本文将详细介绍humans.tx ...

  5. 基于jQuery开发的手风琴插件 jquery.accordion.js

     1.插件代码 少说多做,基于jQuery的手风琴插件jquery.accordion.js的代码:  /* * 手风琴插件说明: * 1.treeTrunk对应树干 * 2.treeLeaf对应树叶 ...

  6. C++ STL Binary search详解

    一.解释 以前遇到二分的题目都是手动实现二分,不得不说错误比较多,关于返回值,关于区间的左闭右开等很容易出错,最近做题发现直接使用STL中的二分函数方便快捷还不会出错,不过对于没有接触过的同学,二分函 ...

  7. Presto向分区表快速插入数据时出现'target directory already exists'的原因

    因为项目使用Presto作为ETL使用,需要将关系库中的数据导入到Hive中.目前关系库中的数据每天导入一次,在Hive中以天为间隔创建新的分区.思路是正确的,但是在使用的过程中,发现将少量关系库中的 ...

  8. FarmCraft[POI2014]

    题目描述 In a village called Byteville, there are   houses connected with N-1 roads. For each pair of ho ...

  9. Oracle中dblink如何使用

    Oracle中dblink应用小结Oracle应用服务器OS   1.查看数据库的global_name        SELECT * FROM GLOBAL_NAME;    2.查看global ...

  10. 对图像组成不了解?这样学习Matplotlib必走弯路!

    在学习Matplotlib的过程中,大家一定会遇到这样那样的问题,比如说,背景图怎么设置?坐标轴怎么设置?坐标轴上的刻度值怎么设置?怎样在PyQt中添加Matplotlib绘图模块? 其实想要学好用好 ...