在主线程中慎用WaitForSingleObject (WaitForMultipleObjects)

下面的代码我调试了将近一个星期hitwall.gif,你能够看出什么地方出了问题吗?

线程函数:

None.gif DWORD WINAPI ThreadProc(
None.gif    
while ( ! bTerminate)
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
// 从一个链表中读取信息并且插入到CListCtrl中
InBlock.gif        
// CListCtrl的句柄是通过线程参数传递进来的
InBlock.gif
        for(;;)
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif           ReadInfoFromList();
InBlock.gif           InsertToCListCtrl();
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }

None.gif}
None.gif
主线程中使用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用下面的代码替换:
None.gif while (TRUE)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
InBlock.gif    DWORD result ; 
InBlock.gif    MSG msg ; 
InBlock.gif
InBlock.gif    result 
= MsgWaitForMultipleObjects(1&readThreadHandle, 
InBlock.gif        FALSE, INFINITE, QS_ALLINPUT); 
InBlock.gif
InBlock.gif    
if (result == (WAIT_OBJECT_0))
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
break;
ExpandedSubBlockEnd.gif    }
 
InBlock.gif    
else 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        PeekMessage(
&msg, NULL, 00, PM_REMOVE);
InBlock.gif        DispatchMessage(
&msg); 
ExpandedSubBlockEnd.gif    }
 
ExpandedBlockEnd.gif}

None.gif


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

转载于:https://www.cnblogs.com/shootingstars/archive/2004/07/15/24602.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值