现在的位置: 首页 > 综合 > 正文

WaitForSingleObject 的问题

2018年06月08日 ⁄ 综合 ⁄ 共 1872字 ⁄ 字号 评论关闭

WaitForSingleObject的问题

 

最近在Windows Mobile 上使用基于SmartDevice的ActiveX的时候,遇到了一些问题,就是执行一个简简单单的启动程序的函数,如ShellExecuteEx... 就会导致机器死机。关于这个问题,后来,发现是由于WaitForSingleObject函数导致。

 

下面就介绍一下WaitForSingleObject函数的使用:

 

WaitForSingleObject
当指定的对象处于有信号状态或者等待时间结束的状态时,此函数返回。
DWORD WaitForSingleObject(
  HANDLE hHandle,
  DWORD dwMilliseconds
);
参数:
hHandle:指定对象或事件的句柄;
dwMilliseconds: 等待时间,以毫妙为单位,当超过等待时间时,此函数将返回。如果该参数设置为0,则该函数立即返回,如果设置为INFINITE,则该函数直到有信号才返回。
返回值:
如果此函数成功,该函数的返回之标识了引起该函数返回的事件。返回值如下:
  WAIT_ABANDONED(0x00000080L)
  指定的对象是一个互斥对象,该对象没有被拥有该对象的线程在线程结束前释放。互斥对象的所有权被同意授予调用该函数的线程。互斥对象被设置成为无信号状态。
  WAIT_OBJECT_0 (0x00000000L)
  指定的对象出有有信号状态。
  WAIT_TIMEOUT (0x00000102L)
  超过等待时间,指定的对象处于无信号状态
如果失败,返回 WAIT_FAILED;
备注:
此函数检查指定的对象或事件的状态,如果该对象处于无信号状态,则调用线程处于等待状态,此时该线程不消耗CPU时间

 

一些需要注意的问题:

 


线程函数:

DWORD WINAPI ThreadProc(
    

while (
!
bTerminate)
    


{
        

//  从一个链表中读取信息并且插入到CListCtrl中
        

//  CListCtrl的句柄是通过线程参数传递进来的


         for
(;;)
       


{
           ReadInfoFromList();
           InsertToCListCtrl();
        }


    }


}

主线程中使用CreateThread启动线程。

当想终止子线程时,在主线程中:
bTerminate = TRUE;
WaitForSingleObject(threadHandle, INFINITE);
可是,以运行到WaitForSingleObject,子线程就Crash了。

为什么呢?

问题原因:
后来我终于在InsertItem的反汇编中发现了如下的代码
call dword ptr [__imp__SendMessageA@16 (7C141B54h)]
可见,InsertItem是必须借助消息循环来完成任务的。如果我们在主线程中WaitForSingleObject了,必然导致主线程阻塞,也就导致了消息循环的阻塞,最终导致工作线程Crash掉了*_*

解决方案:
为了解决在主线程中Wait的问题,微软专门设计了一个函数MsgWaitForMultipleObjects,这个函数即可以等待信号 (thread,event,mutex等等),也可以等待消息(MSG)。即不论有信号被激发或者有消息到来,此函数都可以返回。呵呵,那么我的解决办 法也就出来了。
将上面的WaitForSingleObject用下面的代码替换:

while
(TRUE)


{

    DWORD result ; 
    MSG msg ; 

    result 

=  MsgWaitForMultipleObjects(
1
&
readThreadHandle, 
        FALSE, INFINITE, QS_ALLINPUT); 

    

if  (result 
==
 (WAIT_OBJECT_0))
    


{
        

break ;
    }

 
    

else  
    



        PeekMessage(

& msg, NULL, 
0
0
, PM_REMOVE);
        DispatchMessage(

& msg); 
    }

 
}




总结:
如果在工作线程中有可能涉及到了消息驱动的API,那么不能在主线程中使用WaitForSingleObject一类函数,而必须使用上述的方案。

 

我们的ActiveX中同样是这样的问题导致

抱歉!评论已关闭.