示意代码:

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. html5绘图笔记纪要

    在html5之前,前端是无法再html页面上动态绘制图片 html5新增了一个canvas元素,相当于一个画布,可以获取一个CanvasRenderingContext2D对象 CanvasRende ...

  2. finereport连接mysql8.0的解决办法

    1.具体连接操作 首先将mysql-connector-java-8.0以上的jar包放到FindReport安装目录下的webapps下的WEB-INF下的lib下. 打开finereport,找到 ...

  3. git.ZC一套命令_稀疏签出(sparse-checkout)

    1. git init git remote add origin https://gitee.com/?????/movieHome.git git config core.sparsechecko ...

  4. win10安装mysql时报错[MY-012576] [InnoDB] Unable to create temporary file; errno: 2

    报错信息 解决: 在my.ini文件里面的 [mysqld]区段内加入: #自己指定的临时文件目录 tmpdir="临时目录" 添加好后初始化成功 接下来启动mysql服务的时候报 ...

  5. Spring框架学习总结

    一.Spring概述 1.什么是Spring? Spring是一个优秀轻量级的框架,是Java中使用最多的框架,Spring框架具有轻量.控制反转.面向切面.容器.框架.MVC的特点. 2.Sprin ...

  6. Linux yum 命令篇

    yum( Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器. 基於RPM包管理,能够从指定的服务器自动下载RPM包 ...

  7. Zend_Cache的使用

    一.Zend_Cache快速浏览 Zend_Cache 提供了一个缓存任何数据的一般方法. 在Zend Framework中缓存由前端操作,同时通过后端适配器(File, Sqlite, Memcac ...

  8. Yii2.0 limit(1)与one()

    ActiveRecord中的limit(1)与one()的区别 (new \yii\db\Query())->from('user')->limit(1)->one() public ...

  9. Java关于继承中的内存分配

    1.定义         super:当前对象的父类对象         this   :当前对象,谁调用this所在的方法,this就是哪一个对象.   2.内存分析 另一个例子: public s ...

  10. PCIe事务层包TLP Header详解

    1.事务层包的一般格式: 包的header为3DW(double word)或者4DW(一个DW代表4字节),数据负载为1~1024DW(即4~4096byte,最大4M),TLP Digest可选, ...