今天一天把多线程编程小觑了一下。主要在主线程与用户线程间同步问题。上网一搜结果发现遇到类似问题的人还不少,来总结一下。
首先,主线程是不应该使用WaitForSingleObject(HANDLE)这样的阻塞函数的,我觉的主要还是要了解该函数的特性,该函数不止是阻塞用户设置的HANDLE句柄,同时阻塞了整个主线程的消息队列,用户事件等等。造成的结果是,主线程死掉了。
在主线程是界面程序时,体现的更加严重,界面完全就卡死了。那么,在加上用户线程中有对主界面线程操作功能的函数时,那就一命呜呼了(调任务管理器吧)。原因了?主线程被阻塞了,所有的消息事件都被屏蔽了。而这时候,用户线程向界面操作,相当于发消息,那不也卡死了。主线程与用户线程相互纠正不放,最后之后重启任务了。
这种情况怎么办?首先在用户线程中设置事件未激活(ResetEvent(m_hEvent))。在用户线程的时候将事件激活((SetEvent(m_hEvent))。额!你发现了,不还是要在主线程中阻塞等待事件被激活嘛?
确实要这样,但是使用的是另外一个API了。
DWORD WINAPIMsgWaitForMultipleObjects(
__in DWORD nCount,
__in const HANDLE *pHandles,
__in BOOL bWaitAll,
__in DWORD dwMilliseconds,
__in DWORD dwWakeMask
);
while(TRUE)
{
DWORD dwWaitRet ;
MSG msg ;
dwWaitRet = MsgWaitForMultipleObjects(1,&readThreadHandle,
FALSE, INFINITE, QS_ALLINPUT);
if (dwWaitRet == (WAIT_OBJECT_0))
{
break;
}
else
{
PeekMessage(&msg, NULL, 0, 0,PM_REMOVE);
DispatchMessage(&msg);
}
}
当然还有别的选择:
while(WaitForSingleObject(hThread,0)!=WAIT_OBJECTS_0)
{
sleep(10);
}
看了一篇分析使用TerminalThread/SuspendThread的博客,刚开始自己纠结的时候,就想着使用了。看了这个博客,以后再也不敢了。
http://blog.csdn.net/magictong/article/details/6304439
另一篇也不错,提供了安全的使用SuspendThread的方法,按照博文上说的:"对于这些风险,我们亲爱的Jeffrey Richterand Christophe Nasarre说,你爱用不用,我也没辙,反正我把幺蛾子都告诉你了,剩下的就看你的胆量了~"
http://blog.csdn.net/chris820313/article/details/6718479
还有一篇讲线程同步的,也觉的不错,大家可以瞅瞅!
http://blog.csdn.net/benjiamen/article/details/1658328