S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

MsgWaitForMultipleObjects 后遗症

Posted on 2009-04-22 23:27 S.l.e!ep.¢% 阅读(3809) 评论(3)  编辑 收藏 引用 所属分类: VC
调用SendMessage 产生死锁的问题分析      之后,我在界面程序中不再使用 WaitForSingleObject 了,而改用如下的函数
 
DWORD WaitObjectAndMsg(HANDLE hEventThread, DWORD dwMilliseconds)
 {
  BOOL  bWait   =  TRUE;
  DWORD dwEvt = 0;
  
  while(bWait)
  {
   DWORD dwEvt = ::MsgWaitForMultipleObjects(1 , &hEventThread, FALSE, dwMilliseconds, QS_ALLINPUT);
   
   switch (dwEvt)
   {
   case WAIT_OBJECT_0:       
    {
     return WAIT_OBJECT_0;
    }
    break;
    
   case WAIT_OBJECT_0 + 1:    
    {
     MSG msg;
     while ( ::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
     {
      if( WM_CLOSE == msg.message || WM_QUIT == msg.message )
      {
       return WAIT_FAILED;
       break;
      }
      else 
      {
       PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);

        ::TranslateMessage(&msg);  
        ::DispatchMessage(&msg);   
      }
     }
     break;
    }
    
   default:  
    {
     return dwEvt;
     break;
    }
    
   } 
  }
  
  return dwEvt;
 }
 
这个函数看起来不错,在等待一个 Object 的同时,还可以边等待,边处理消息
今天才发现,这样处理有缺陷

如果在等待一个Object 时,哪怕只有 0.00001 秒,这里如果一个不小心处理了消息

    那么 很自然会走到这个语句   ::DispatchMessage(&msg);     

经过调试发现,         ::DispatchMessage(&msg);    是阻塞的,

如果在处理消息的函数里,调用了一个

CDialog dlg;
dlg.DoModal();     这里也是阻塞的, 如果这个窗口一直不关闭,

即使这时候 Object 已经响应了,但这个函数仍然不返回,,,,,,,因为它在双重的消息处理中。。。。。。。


Feedback

# re: MsgWaitForMultipleObjects 后遗症  回复  更多评论   

2009-04-23 10:56 by 飘飘白云
这个死锁问题可以看看the old new thing上的讨论:

http://blogs.msdn.com/oldnewthing/archive/2005/02/17/375307.aspx

# re: MsgWaitForMultipleObjects 后遗症  回复  更多评论   

2009-04-23 12:45 by 陈梓瀚(vczh)
将任何存在send关系的线程连接起来,构成一个有向图,不要产生环。设计的时候就得这样。不然就用postmessage

# re: MsgWaitForMultipleObjects 后遗症  回复  更多评论   

2009-04-23 13:34 by kevin.c
请把逻辑处理与GUI处理分成不同的线程

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理