SetwindowText 之线程阻塞
示意代码:
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 之线程阻塞的更多相关文章
- 【Javascript】解决Ajax轮询造成的线程阻塞问题(过渡方案)
一.背景 开发Web平台时,经常会需要定时向服务器轮询获取数据状态,并且通常不仅只开一个轮询,而是根据业务需要会产生数个轮询.这种情况下,性能低下的Ajax长轮询已经不能满足需求,频繁的访问还会造成线 ...
- java并发编程(四)守护进程 线程阻塞的四种情况
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17099981 守护线程 Java中有两类线程:User Thread(用户线程).Da ...
- jQuery同步Ajax带来的UI线程阻塞问题及解决办法
俗话说不作死就不会死,今天作死了一回,写了一个比较二逼的函数,遇到了同步Ajax引起的UI线程阻塞问题,在此记录一下. 事情起因是这样的,因为页面上有多个相似的异步请求动作,本着提高代码可重用性的原则 ...
- CountDownLatch线程阻塞用法实例
在编写多线程的工作中,有个常见的问题:主线程(main) 启动好几个子线程(task)来完成并发任务,主线程要等待所有的子线程完成之后才继续执行main的其它任务. 默认主线程退出时其它子线程不会停, ...
- 【性能诊断】七、并发场景的性能分析(windbg案例,线程阻塞)
简单整理一个测试Demo,抓取dump并验证,步骤如下: Symbol File Path:SRV*C:\Symbols*http://msdl.microsoft.com/download/symb ...
- Android Studio学习随笔-UI线程阻塞以及优化
我们在使用手机的时候,经常会遇到一个问题:先是卡死,然后跳出该程序无响应,是否关闭的提示(当然有可能是我们手机性能太差=.=)这是因为线程的阻塞引起的,在这里我讲述一下UI线程,一般处理程序会在UI线 ...
- JAVA并发实现四(守护线程和线程阻塞)
守护线程 Java中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) 用户线程即运行在前台的线程,而守护线程是运行在后台的线程. 守护线程作用是为其他前台 ...
- 第10讲- UI线程阻塞及其优化
第10讲UI线程阻塞及其优化 .UI 阻塞demo (首先在activity_main.xml中放置两个button,分别命名为button1,button2) //首先设置一个button1用来进行 ...
- 转:【Java并发编程】之四:守护线程与线程阻塞的四种情况
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17099981 守护线程 Java中有两类线程:User Thread(用户线 ...
随机推荐
- maven spark Scala idea搭建maven项目的 pom.xml文件配置
1.pom.xml文件配置,直接上代码. <?xml version="1.0" encoding="UTF-8"?> <project xm ...
- (转)Eclipse - CDT使用GDB调试C++的问题-无源文件命名(No source file named)
http://tech.ddvip.com/2014-09/1411618782213496.html Eclipse CDT调试C++, 使用的Unix的调试器GDB; 由于在Unix下, 文件的目 ...
- python+selenium模拟键盘输入
from selenium.webdriver.common.keys import Keys #键盘导入类 --------------------------------------------- ...
- [19/09/16-星期一] Python的运算符和条件判断语句
一.运算符 (1)算术运算符 + 加法运算符(如果是两个字符串之间进行加法运算,则会进行拼串操作) a = 10 + 5 计算 a = 'hello' + ' ' + 'world' 拼串 - ...
- 计算机系统结构总结_Branch prediction
Textbook:<计算机组成与设计——硬件/软件接口> HI<计算机体系结构——量化研究方法> QR Branch Prediction 对于下面的指令: ...
- 剑指offer-用两个栈来实现一个队列-队列与栈-python
用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 思路:使用两个栈,stackA 用来接收node stackB 用来接收 stackA 的出栈 # -*- cod ...
- tabcontrol动态生成选项卡,并且在选项卡中添加窗体
http://blog.csdn.net/zx13525079024/article/details/6084733 今天在论坛上看到有人问到,如果在点击TRVEVIEW时动态生成tabcontrol ...
- redis基础及redis特殊场景使用描述
数据类型 String set list hash zset redis原理 单线程:redis是单线程+io多路复用:检查文件描述的就绪状态 对比memchached:多线程+锁 redis优势 解 ...
- goaccess实现nginx实现日志可视化
一:goaccess模块 goaccess模块是将nginx的日志定向到goaccess模块里实现,原理很简单,只要将文件定向到那里就可以,goaccess是已经集成好显示数据的一个页面,非常的美观和 ...
- Docker下载镜像并创建容器运行
在linux系统中安装完成docker后,我们开始进行docker的镜像.容器的使用. 在使用docker时,首先要明确的两个概念:image(镜像) 与 container (容器) image: ...