Windbg调试互斥体(Mutex)死锁

一. 测试代码

#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 查看所有线程调用堆栈:
214032-20170823144248121-1435105746.png

从线程#1栈帧03可以看到其正在等待句柄00000038。
从线程#2栈帧03可以看到其正在等待句柄00000034。
即:
线程#1(ID:22f4)--->等待句柄38
线程#2(ID:33bc)---> 等待句柄34

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

从图中可以看到:
句柄00000034为名为MutexA的互斥体,被线程ID:2264 拥有。
句柄00000038为名为MutexB的互斥体,被线程ID:33bc 拥有。

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

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

转载于:https://www.cnblogs.com/jiangxueqiao/p/7418074.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值