博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SetwindowText 之线程阻塞
阅读量:5240 次
发布时间:2019-06-14

本文共 1057 字,大约阅读时间需要 3 分钟。

示意代码:

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 消息映射框架

 

转载于:https://www.cnblogs.com/Esperanto/p/3227478.html

你可能感兴趣的文章
中文系统 上传file的input显示英文
查看>>
比callback更简洁的链式执行promise
查看>>
android permission
查看>>
【译】在Asp.Net中操作PDF - iTextSharp - 使用字体
查看>>
.net 文本框只允许输入XX,(正则表达式)
查看>>
实验2-2
查看>>
MongoDB遇到的疑似数据丢失的问题。不要用InsertMany!
查看>>
android smack MultiUserChat.getHostedRooms( NullPointerException)
查看>>
IOS Google语音识别更新啦!!!
查看>>
[置顶] Linux终端中使用上一命令减少键盘输入
查看>>
BootScrap
查看>>
【Python学习笔记】1.基础知识
查看>>
梦断代码阅读笔记02
查看>>
selenium学习中遇到的问题
查看>>
[Linux]PHP-FPM与NGINX的两种通讯方式
查看>>
Java实现二分查找
查看>>
架构图-模型
查看>>
黑马程序员_Java基础枚举类型
查看>>
UIImage 和 iOS 图片压缩UIImage / UIImageVIew
查看>>
django ORM创建数据库方法
查看>>