示意代码:

CriticalSection g_Section;
CDialog g_Dlg;

// 工作线程函数
UINT TreadFunc_A(PVOID para)
{
Sleep(10);

g_Section.Lock();

Sleep(3000);
g_Dlg.m_Show_Edit.SetWindowText("TreadFuncA");
// Beep(400,20);

g_Section.Unlock();
}

// 窗口按钮消息函数
void CDialog::OnButton1()
{
g_Section.Lock();

g_Dlg.m_Show_Edit.SetWindowText("OnButton1");
// Beep(800,20);
g_Section.Unlock();
}

死锁出现条件:
TreadFunc_A 进入 g_Section.Lock() 临界区
在没有释放临界锁之前OnButton1()触发,g_Section.Lock() 阻塞等待
....永远都等不到了!

实验:
如果把g_Dlg.m_Show_Edit.SetWindowText替换成Beep,测滴答滴答的运行OK,不会出现死锁。
看来问题出在SetWindowText上了。

分析:
导致死锁的一个隐含机制:SetWindowText 的实现使用了 SendMessage(WM_SETTEXT,...)
而SendMessage是阻塞调用,等待窗口处理函数完成才返回。同时OnButton1也是窗口消息处理函数的回调映射,
所以 g_Dlg.m_Show_Edit.SetWindowText("TreadFuncA"),在等待窗口消息处理函数的返回,线程被阻塞。
而OnButton1占用了窗口消息函数执行,申请临界锁被阻塞。这样工作线程TreadFunc_A 占用临界锁同时等
待窗口消息处理函数的返回,而界面线程占用窗口消息处理函数同时等待临界锁,于是就永远死翘翘的等下去了。

结束语:
MFC下面厚厚的封装,鬼才知道是什么实现机制。为了吃块糖,只需要剥开糖纸即可,为什么还要了解糖的加工工艺。
吃别人的东西,直管往嘴里放就得了,出了问题再想办法,也只能这么着了。

扩展阅读:

1)Windows 窗口消息原理

2)SendMessage的实现机制

3)MFC 消息映射框架

SetwindowText 之线程阻塞的更多相关文章

  1. 【Javascript】解决Ajax轮询造成的线程阻塞问题(过渡方案)

    一.背景 开发Web平台时,经常会需要定时向服务器轮询获取数据状态,并且通常不仅只开一个轮询,而是根据业务需要会产生数个轮询.这种情况下,性能低下的Ajax长轮询已经不能满足需求,频繁的访问还会造成线 ...

  2. java并发编程(四)守护进程 线程阻塞的四种情况

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17099981 守护线程   Java中有两类线程:User Thread(用户线程).Da ...

  3. jQuery同步Ajax带来的UI线程阻塞问题及解决办法

    俗话说不作死就不会死,今天作死了一回,写了一个比较二逼的函数,遇到了同步Ajax引起的UI线程阻塞问题,在此记录一下. 事情起因是这样的,因为页面上有多个相似的异步请求动作,本着提高代码可重用性的原则 ...

  4. CountDownLatch线程阻塞用法实例

    在编写多线程的工作中,有个常见的问题:主线程(main) 启动好几个子线程(task)来完成并发任务,主线程要等待所有的子线程完成之后才继续执行main的其它任务. 默认主线程退出时其它子线程不会停, ...

  5. 【性能诊断】七、并发场景的性能分析(windbg案例,线程阻塞)

    简单整理一个测试Demo,抓取dump并验证,步骤如下: Symbol File Path:SRV*C:\Symbols*http://msdl.microsoft.com/download/symb ...

  6. Android Studio学习随笔-UI线程阻塞以及优化

    我们在使用手机的时候,经常会遇到一个问题:先是卡死,然后跳出该程序无响应,是否关闭的提示(当然有可能是我们手机性能太差=.=)这是因为线程的阻塞引起的,在这里我讲述一下UI线程,一般处理程序会在UI线 ...

  7. JAVA并发实现四(守护线程和线程阻塞)

    守护线程     Java中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) 用户线程即运行在前台的线程,而守护线程是运行在后台的线程. 守护线程作用是为其他前台 ...

  8. 第10讲- UI线程阻塞及其优化

    第10讲UI线程阻塞及其优化 .UI 阻塞demo (首先在activity_main.xml中放置两个button,分别命名为button1,button2) //首先设置一个button1用来进行 ...

  9. 转:【Java并发编程】之四:守护线程与线程阻塞的四种情况

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17099981      守护线程   Java中有两类线程:User Thread(用户线 ...

随机推荐

  1. 基于 Timer是一种定时器工具

    没有依赖 通过Timer中的schedule方法启动定时任务 一般不采用此方法 /** * ------------------------------------------------------ ...

  2. realloc ------ 扩大malloc得到的内存空间

    char* p = malloc(1024);char* q = realloc(p,2048); 现在的问题是我们应该如何处理指针 p. 刚开始按照我最直观的理解,如果就是直接将 p = NULL; ...

  3. [19/09/18-星期三] Python中的序列

    一. # 第四章 序列(视频58-76) ## 列表(list) - 列表是Python中的一个对象 - 对象(object)就是内存中专门用来存储数据的一块区域 - 之前我们学习的对象,像数值,它只 ...

  4. windows上Appium安装和使用

    1.Appium安装相关依赖工具: Android Studio或者Android SDK:https://developer.android.com/studio/Appium Desktop: h ...

  5. Square HDU 1518 搜索

    Square HDU 1518 搜索 题意 原题链接 给你一定若干个木棒,让你使用它们组成一个四边形,要求这些木棒必须全部使用. 解题思路 木棒有多种组合方式,使用搜索来进行寻找,这里需要进行优化,不 ...

  6. osi七层模型??

    1.应用层:提供用户服务,例如处理应用程序,文件传输,数据管理      (HTTP.RTSP.FTP) 2.表示层:做数据的转换和压缩,加解密等 3.会话层:决定了进程间的连接建立,选择使用什么样的 ...

  7. switch语句能否作用在byte,long,string上

    switch是java中的多分支结构.在switch(expr)中,expr只能是一个整数表达式,或者是枚举常量,整数表达式可以是int基本类型也可以是Integer包装类型,由于byte,short ...

  8. [MyBatis]诡异的Invalid bound statement (not found)错误

    转自:https://blog.csdn.net/z69183787/article/details/48933481 自从开始使用Maven管理项目,最近在配置MyBatis的Mapper,在Ecl ...

  9. ST7735和ST7789驱动

    /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __LCD_H #de ...

  10. 用Python编写一个ftb

    程序文件结构 具体代码实现 服务端: 执行文件bin/ftb_server import os,sys PATH = os.path.dirname(os.path.dirname(os.path.a ...