一. 测试代码

#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. xshell常用命令

    常用的命令: suse linux 常用命令 (1) 命令ls--列出文件 ls 显示当前目录文件 ls -la 给出当前目录下所有文件的一个长列表,包括以句点开头的"隐藏"文件 ...

  2. C++学习(七)入门篇——C++算数运算符

    以下介绍5种C++基本运算符 +.-.×./.% 注意/为第一个数除以第二个数,结果为商的整数部分,小数部分被丢弃 %求模,两个操作数必须是整型,它生成第一个数除以第二个数的余数 如果其中一个是负数, ...

  3. SVN分支/合并操作小记

    一.前言 说来惭愧,鄙人从事开发多年,使用svn已经好几个年头了,但是却仅限于update.commit.compare之类的操作,最近想到github上学习别人写的NIO源码,顺便去熟悉git的使用 ...

  4. [js] 小谈 export (没总结完)

    作用 导出变量/类 等等 用法 index.js 文件 export default name 仅导出一个变量 import name from './index.js' index.js 文件 ex ...

  5. wpf的一些总结

    wpf技巧 隐藏控件不占空间,设置visibility为:Collapsed tabcontrol的高度宽度跟随界面的大小变化:属性height\width绑定grid的actualheight\ac ...

  6. Redis-位图法实现简单统计

    比如一个网站有1亿个用户, 现在要统计一周内连续登录的用户 方法: 可以用一个字节8个位表示7个人, 首位不算固定为0, 若某人周一登录则置为1, 没登录则为0 127.0.0.1:6379> ...

  7. 53. leetcode557. Reverse Words in a String III

    557. Reverse Words in a String III Given a string, you need to reverse the order of characters in ea ...

  8. 超超超简单的bfs——POJ-1915

    Knight Moves Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 26102   Accepted: 12305 De ...

  9. 对于JavaScript中this关键字的理解

    这是我第二遍学this了,第一遍学的懵懵的.this指哪里都是凭我一个男人的直觉然后控制台输出看看对不对. 刚查了书.博客.视频.理解差不多了.毕竟菜鸡me: 一.首先介绍下什么是this this是 ...

  10. 浅谈odoo 后台与前端文件(附件)的存储与下载

    odoo 后台与前端文件(附件)存储与下载实现 笔记太多了很乱,想想还是写博客的好,慢慢更 当然了,前提是你已经配好了odoo开发环境 一.odoo后台界面实现附件的上传和下载 1).在应用中搜索下图 ...