小议避免进程退出时的死锁
来源:互联网 发布:中国食品出口数据 编辑:程序博客网 时间:2024/05/29 17:22
——Windows GUI程序中使用线程的心得体会
①避免在工作者线程中使用SendMessage,改用PostMessage比较好。
原因是这样的,以一个普通程序退出为例,我们经常会使用以下方式构建退出逻辑:
主线程正在消息处理函数
工作者线程正在处理任务
void OnDestroy(){//WM_DESTROY
//1发送退出消息或命令给工作者线程:
SetEvent(m_hStop);
//2等待线程退出:
WaitForSingleObject(m_hThread, INFINITE);
// DebugPoint;
m_hThread=NULL;
//3销毁窗口资源
CWnd::OnDestroy();
}
void DoWork(){
char strTitle[100]={0};
while(WAIT_OBJECT_0 != WaitForSingleObject(m_hStop, 0)){
Sleep(5000);//模拟工作线程的任务处理
//访问界面资源:
SendMessage(m_hMainWnd, WM_GETTEXT, sizeof(strTile) , strTitle);
//DebugPoint;
Sleep(0);
}
CloseHandle(m_hThread);
}
如上所示,只要主线程开始处理WM_DESTROY消息后,只有等到OnDestroy返回,主线程才会处理下一个Windows消息。一旦OnDestroy函数开始执行且还没有返回,DoWork中发出的WM_GETTEXT消息就不会被主线程处理,使用SendMessage后工作者线程就会等待主线程处理WM_GETTEXT进入休眠,注意这种休眠无法使用ResumeThread唤醒(即使唤醒只要主线程没有处理WM_GETTEXT消息也会继续睡过去)。而这时OnDestroy函数正在用WaitForSingleObject等待DoWork检测m_hStop信号退出线程,所以两者互相等待都进入了休眠,这样就产生了死锁。
很多朋友一定会说,那就把OnDestroy里WaitForSingleObject去掉直接往后执行不就没有死锁了么?死锁是没有了,由于OnDestroy函数的主要职责就是负责释放资源,接下来它一定会调用类似CWnd::OnDestroy()函数来销毁窗口资源,这样一来DoWork里就很有可能因为访问界面资源而崩溃。
所以,②应该避免在工作者线程中直接访问界面资源,包括不要使用GetWindowsText等函数。可以把要显示到界面上的数据,放进一个自己构建的队列中,然后使用PostMessage发出特定的消息或者用户自定义的消息,由消息处理函数去完成。
③如果必须在线程里访问界面资源怎么办?可以使用类似MFC中的界面线程。
下面是我在工作者线程里直接访问界面资源的方法,利用消息泵:
工作者线程正在处理任务
void DoWork(){
char strTitle[100]={0};
MSG sMsg={0};
while(WAIT_OBJECT_0 != WaitForSingleObject(m_hStop, 0)){
Sleep(5000);//模拟工作线程的任务处理
//到消息队列里取出关注的消息WM_DESTROY:
if(PeekMessage(&sMsg, m_hMainWnd, WM_DESTROY, WM_DESTROY, PM_NOREMOVE)){
break;
}
//尽快访问界面资源,这里还是有可能死锁的,最好不要在这中间插入指令。
SendMessage(m_hMainWnd, WM_GETTEXT, sizeof(strTile) , strTitle);
//DebugPoint;
Sleep(0);
}
//退出线程前释放相应资源:
CloseHandle(m_hThread);
}
上面也许不是解决退出死锁的万能方法,只是我的一点心得,希望大家有更好的办法也贴上来。
- 小议避免进程退出时的死锁
- 进程异常退出导致死锁的解决办法
- DLL进程退出时出现死锁问题
- 死锁的避免
- 避免死锁的建议
- 进程同步及避免死锁经典问题
- 银行家算法 避免进程发生死锁
- 死锁 死锁的检测 预防和避免
- 死锁 避免死锁的常见方法
- 死锁和避免出现死锁的方式
- 死锁的产生以及如何避免死锁
- 死锁发生的条件,如何避免死锁
- 死锁及避免死锁的银行家算法
- 死锁的产生和避免
- 死锁的避免和预防
- 死锁的产生,处理,避免
- 死锁的产生及其避免
- 死锁的产生及避免
- C#注册表操作类 实用操作函数
- c#XML文件操作类 实用的XML操作
- 开发团队是否需要专门测试人员,大型电商网站架构分享
- c# 数据库操作类sql server篇
- ASP.Net小结
- 小议避免进程退出时的死锁
- c# 无损高质量压缩图片代码
- Exchange 2003 升级到Exchange 2010 之启用HUB\CAS的防垃圾邮件代理!
- WMI学习
- 第7章 精通常用的Java类
- Java 找数组中的元素
- 关于servlet的中的request和response两个对象的详细介绍
- linux引导流程
- 项目就像个受精卵,产品才是儿子