zoukankan      html  css  js  c++  java
  • 主线程里面使用WaitForSingleObject (WaitForMultipleObjects)需要考虑的情况(转)

    下面的代码能够看出什么地方出了问题吗?

    线程函数:

     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, 00, PM_REMOVE);
            DispatchMessage(
    &msg); 
        }
     
    }


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

  • 相关阅读:
    hadoop 第二次启动 50030端口能打开 50070端口打不开
    hadoop配置(个人总结)
    发布版本化您的应用
    hive 初始化运行流程
    android Content Providers 内容提供者
    hive Cli常用操作(翻译自Hive wiki)
    用于展现图表的50种JavaScript库
    STL list transfer (迁移)实现
    pop_heap算法 (将根节点置于容器尾部后重调heap结构)
    sgi STL源码下载
  • 原文地址:https://www.cnblogs.com/pbreak/p/3392601.html
Copyright © 2011-2022 走看看