原文:http://www.cnblogs.com/jcss2008/archive/2009/02/23/1396803.html
下面的代码我调试了将近一个星期
,你能够看出什么地方出了问题吗?
线程函数:
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一类函数,而必须使用上述的方案。
本文探讨了在Windows环境下,由于主线程使用WaitForSingleObject等待子线程结束而导致子线程崩溃的问题。通过分析发现,子线程中使用了依赖消息循环的API,而主线程的等待操作阻塞了消息循环,最终导致了子线程的崩溃。文章提供了使用MsgWaitForMultipleObjects替代WaitForSingleObject的方法来解决该问题。
1603

被折叠的 条评论
为什么被折叠?



