一. 测试代码

#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. 【一步一步】Spring 源码环境搭建

    平时项目中基本上都会用到spring,但是源码还没有深入的了解过.趁这段时间稍微空闲点,开始研究下spring 源码.下面是spring 源码的环境搭建. 主要分为如下步骤: ①安装jdk,gradl ...

  2. hadoop 50070 无法访问问题解决汇总

    遇到这个其实不难解决! 解决办法1: [root@djt002 hadoop]# vi /etc/selinux/config 改为 SELINUX=disabled 解决办法2: 查看你的$HADO ...

  3. (一)SQL关联查询的使用技巧 (各种 join)

    ---恢复内容开始--- (一)SQL关联查询的使用技巧 (各种 join) 这几天因为工作的时候,发现自己的sql语句基础不是很好,特意研究了一下,发现sql语句真的是博大精深,sql语句不仅是要查 ...

  4. 运行shell脚本时报错"[[ : not found"解决方法

    问题描述 在运行shell脚本时报错,命令为: sh test.sh 报错如图: 脚本代码如下: #!/bin/bash # file:test.sh # author:13 # date:2017- ...

  5. (转)IBM MQ 创建以及常见问题集锦

    背景:这篇文章还是很全面的,但是很杂乱 后面慢慢整理吧! 1 MQ 消息队列+发送队列+消息通道 接收通道名称与发送端的发送通道名称要一致,修改通道信息后要执行 start channle(chlna ...

  6. Asp.Net MVC-4-过滤器1:认证与授权

    基础 过滤器体现了MVC框架中的Aop思想,虽然这种实现并不完美但在实际的开发过程中一般也足以满足需求了. 过滤器分类 依据上篇分析的执行时机的不同可以把过滤器按照实现不同的接口分为下面五类: IAu ...

  7. Java操作Excel和Word

    这是一个URL它提供了Java项目所推荐的处理此项目所用的类库 http://www.oschina.net/project/tag/258/excel-tools?company=0&sor ...

  8. myeclipse项目部署到idea常见问题

    由于myeclipse是付费产品,经过几次破解不成功后,遂弃之,转投IntelliJ IDEA门下.但这就出现一个问题了,以前用的eclipse.myeclipse以及spring tools sui ...

  9. 13 年的 Bug 调试经验总结(来自蜗牛学院)

    在<Learning From Your Bugs>一文中,我写了关于我是如何追踪我所遇到的一些最有趣的bug. 最近,我回顾了我所有的194个条目,看看有什么经验教训是我可以学习的.下面 ...

  10. Azure 认知服务 (4) 计算机视觉API - 读取图片中的文字 (OCR)

    <Windows Azure Platform 系列文章目录> 微软Azure认知服务的计算机视觉API,还提供读取图片中的文字功能 在海外的Windows Azure认知服务的读取图片功 ...