线程死锁
来源:互联网 发布:淘宝上的pvc地板好不好 编辑:程序博客网 时间:2024/04/28 06:15
你在主线程用了WaitForSingleObject,导致了消息循环的阻塞,界面假死。然后在线程中调用了SetDlgItemText,而SetDlgItemText实际上调用的是SendMessage,而SendMessage要等待主线程处理完毕发送的消息才返回继续执行,而你主线程的消息循环已经阻塞,无法处理消息,导致整个过程“我等你,你等我”,无穷下去
在界面线程不能使用Sleep和WaitForSingleObject之类的函数,比较好的方法是,将句柄作为线程参数传递进线程,当线程结束后发一条消息通知主线程处理完毕
编译器的最优化又可能导致这个问题,使用volatile修饰一下bTerminate
在整个循环过程中(while (!bTerminate) { })bTerminate会被放入CPU的寄存器中,每次
while做判断的时候读取的都是寄存器中的值,即使你在程序中改变了bTerminate为TRUE,
由于最优化的缘故,while循环不会退出,导致线程就象死了一样!也是一种可能!
问题描述:AfxBeginThread创建一个线程后,在线程中操作UI的控件,例如EDIT。在UI的button里停止线程,并等待结束,一般用WaitforsingleObject,但是这个函数会导致UI消息阻塞,如果这个时候线程里正好操作UI控件并需要用到SendMessage,则线程在等待消息发送完,WaitforsingleObject在等待线程,而WaitforsingleObject又阻塞了消息,这样就导致了死循环。下文为解决方法,已经省略,全部可以参考原文地址:
还可以看出:MsgWaitForMultipleObjects实际上在这其中并没有起到什么实质性的作用,只是定期返回而已,那么根据此,可以用固定时间的WaitForSingleObject来代替MsgWaitForMultipleObjects,并且循环等待 ;同时,我们也没有必要手动DispatchMessage,只需要PeekMessage即可,需要注意的是如果删除了DispatchMessage,在PeekMessage时不能将消息从队列取走。代码如下:
- DWORD dwRet = 0;
- MSG msg;
- while (TRUE)
- {
- dwRet = WaitForSingleObject(m_hThread, 50);
- switch(dwRet)
- {
- case WAIT_OBJECT_0:
- break; //break the loop
- case WAIT_TIMEOUT :
- PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
- continue;
- default:
- break; // unexpected failure
- }
- break;
- }
经过测试,代码运行正确!
当然,由于MsgWaitForMultipleObjects是基于消息驱动的返回,WaitForSingleObject只是普通的定时返回,而本文的情况就是由于消息阻塞造成的,所以MsgWaitForMultipleObjects比WaitForSingleObject在应用时时效性更好,如果改成WaitForSingleObject,在测试中感觉会有略为滞后,所以实际还是以MsgWaitForMultipleObjects为佳。
- 线程死锁
- 线程死锁
- 线程死锁
- 线程死锁
- 线程死锁
- 线程死锁
- 线程死锁
- 线程死锁
- 线程死锁
- 线程-死锁
- 线程死锁
- 线程死锁
- 线程死锁
- 线程死锁
- 线程死锁
- 线程死锁
- 线程死锁
- 线程死锁
- 一、C++ 分配与释放存储空间
- FPGA与CPLD的概念及其区别
- fl2440 移植u-boot-2010.09全纪录4---------u-boot支持从nandflash启动
- ppp、socket、PDP之间的关系
- 使用LSP进行带宽限制(Net limiter)
- 线程死锁
- TSM sch不自动启动
- 设计模式详解之抽象工厂模式
- hibernate中的悲观锁和乐观锁的实现
- Linux C 获取进程的退出值
- 抽烟起点
- curl 设置超时,否则会阻塞
- 移动平台3G手机网站前端开发布局技巧汇总(转)
- linux网卡驱动分析之probe函数