主线程与用户线程同步问题

来源:互联网 发布:玉兰与木兰知乎 编辑:程序博客网 时间:2024/05/29 17:39

         今天一天把多线程编程小觑了一下。主要在主线程与用户线程间同步问题。上网一搜结果发现遇到类似问题的人还不少,来总结一下。

         首先,主线程是不应该使用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);

         这里,需要过滤掉系统及用户的事件消息,因为我们只对m_hEvent事件赶兴趣。

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);}

         通过Sleep挂起线程,让另外的线程继续执行。这个没试过,感兴趣的可以体验一下。

         看了一篇分析使用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

 

原创粉丝点击