由sendmessage引发的血案

某项目里使用了soui的通知中心的SRUNONUISYNC实现ui和后台线程之间的同步!发现窗口关闭时后台线程小概率出现随机join后死锁现象!由于这个现象出现的几率很小十分难调试,在我本机甚至无法复现,只得研究代码过程!好在代码量不大,排除几处可能得情况,最后锁定在SRUNONUISYNC上!因为它的原理就是使用SendMessage来实现同步!那么为什么它会发生死锁呢?首先这个关闭动作发生在一个消息处理过程中即鼠标点击事件,这个时候如果SendMessage的情况则分两种,一是来自本ui线程,这个时候它是直接调用窗口过程的这个时候自然没问题,但是这里明显不是来自本线程这个时候SendMessage过来的消息只能进入消息队列等待后面的消息分发而这个时候SendMessage的线程因为SendMessage没得到处理而处于阻塞状态,而另一边ui线程因为等待后台线程join退出也处于阻塞状态造成死锁!找到问题就好处理了,微软似乎也意识到这个坑给我们提供了MsgWaitForMultipleObjects来处理这种情况!此外soui提供的SRUNONUI它是使用postmessage来实现的则无此问题!此外改造sendmessagetimeout来替代sendmessage也是可以的,这两个方法会有另一个问题post方式因为只是把它放进消息队列这个时候如果要操作ui就一定要小心书写代码,因为它执行的时候可能这个ui已经不在了!此外在MsgWaitForMultipleObjects分发消息时还有一个坑点,如果这个消息处理中被阻塞DispatchMessage将会阻塞进而再次引发死锁!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值