今天发现一个怪问题。我在IE里开发了一个ACTIVEX控件,这个控件在IE网页打开的时候,执行一个线程函数,也就是开了一个线程。问题是这样出现的,我首先打开一个IE窗口,然后点击IE的FILE菜单下的NEW WINDOW,这样又开了一个窗口。这两个过程相当于开了两个线程(通过TRACE,发现确实如此)。(说明一下,我用点击IE的STOP按钮来结束我的 ACTIVEX线程。)如果我此时点击其中某个窗口的STOP按钮,发现只能结束一个线程,另外一个线程无法结束。我定义了一个全局信号量hRequestExitEvent,然后用WaitForSingleObject (hRequestExitEvent,INFINITE);来结束线程,这个语句不work.但是如果我用do{}while(WaitForSingleObject (hConnectedEvent,0)==WAIT_TIMEOUT);却可以让两个线程都结束。这种现象,如果我直接打开两个IE窗口,而不是通过 FILE->NEW这种方式,就不会出现这样的问题。困惑,困惑!!
。。
写的有点罗嗦,是因为没有发现问题的本质,希望高手指点一下迷津!谢谢。

解决方案 »

  1.   

    自动重置事件和人工重置事件是不同的,“事件能够通知一个操作已经完成。有两种不同类型的事件对象。一种是人工重置的事件,另一种是自动重置的事件。当人工重置的事件得到通知时,等待该事件的所有线程均变为可调度线程。当一个自动重置的事件得到通知时,等待该事件的线程中只有一个线程变为可调度线程。”
    CreateEvent()中的第二个参数来设置,这是SDK,MFC的话不太清楚,不过应该差不多
      

  2.   

    谢谢楼上的兄弟,我用的是人工重置。用SetEvent()函数来人工激活事件!我的疑惑在于如果我用
    do{....}while(WaitForSingleObject (hConnectedEvent,0)==WAIT_TIMEOUT))这种方式来检查hConnectedEvent的状态的话,那么所有的线程都能够等待到这个事件的激活。但是如果用WaitForSingleObject (hRequestExitEvent,INFINITE);就只能有一个线程可以等待到。很明显,后面这个等待,基本不耗cpu.但是前面的那个却很耗CPU 。
      

  3.   

    WaitForSingleObject (hConnectedEvent,0)==WAIT_TIMEOUT)
    这样WaitForSingleObject会立刻返回的,应为你指定了等待时间为0,而且返回值WAIT_TIMEOUT
    所以就会不停的耗CPU
    下面是对WaitForSingleObject 参数的解释:
    DWORD WaitForSingleObject(
      HANDLE hHandle,        // handle to object to wait for
      DWORD dwMilliseconds   // time-out interval in milliseconds
    );
    Parameters
    hHandle 
    Handle to the object. For a list of the object types whose handles can be specified, see the following Res section. 
    Windows NT: The handle must have SYNCHRONIZE access. For more information, see Standard Access Rights. dwMilliseconds 
    Specifies the time-out interval, in milliseconds. The function returns if the interval elapses, even if the object's state is nonsignaled. If dwMilliseconds is zero, the function tests the object's state and returns immediately. If dwMilliseconds is INFINITE, the function's time-out interval never elapses. 
      

  4.   

    你的do{}while(WaitForSingleObject (hConnectedEvent,0)==WAIT_TIMEOUT);
    会一直执行的,应为你用错了WaitForSingleObject 
      

  5.   

    楼上说得对,不能为dwMillisecond传递0。如果传递了0,WaitForSingleObject函数将总是立即返回。
      

  6.   

    谢谢楼上的兄弟,确实如huang_yu所说,do{}while(WaitForSingleObject (hConnectedEvent,0)==WAIT_TIMEOUT);会一直执行,这样耗CPU,所以我改用WaitForSingleObject (hRequestExitEvent,INFINITE)。然而我的问题是:如果我开了两个线程,而且设置了一个全局的事件hRequestExitEvent,那么当我将这个事件激活时,do{....}while(WaitForSingleObject (hConnectedEvent,0)==WAIT_TIMEOUT))这种方式来检查hConnectedEvent的状态的话,那么所有的线程都能够等待到这个事件的激活。但是如果用WaitForSingleObject (hRequestExitEvent,INFINITE);就只能有一个线程可以等待到。按照道理应该所有的线程都能接受得到阿。为什么两种语句会有两种效果?以上是我的问题!!
      

  7.   

    我试了一下WaitForSingleObject (hConnectedEvent,0)这样只会返回WAIT_OBJECT_0
      

  8.   

    我用老侯所教的多线程中结束线程的方法
    WaitForSingleObject (hConnectedEvent,0)==WAIT_TIMEOUT 
    也是出现一些莫名其妙的问题,到底怎么安全的结束线程?
      

  9.   

    呵呵,我也是用侯杰的方法的.楼上的兄弟,这本书的名字是win32多线程程序设计.
    另外,我已经找到一个我不太理解的方法,解决了我的问题.贴出来让大家瞅瞅!
    是这样的,我在
    WaitForSingleObject (hRequestExitEvent,INFINITE);
    后加上
    if(hRequestExitEvent==NULL)
    hRequestExitEvent=::CreateEvent(NULL,TRUE,FALSE,NULL);
    就可以了.
    因为后来我发现我的析构函数里有这样的语句
    if(hRequestExitEvent!=NULL)
    {
    CloseHandle(hRequestExitEvent);
    hRequestExitEvent=NULL;
    }
    这样就有可能在第二个线程还没有等到的时候,hRequestExitEvent已经被销毁了.
    但是,我还是不能理解为什么用下面这种方式就不会出问题
    do{....}while(WaitForSingleObject (hConnectedEvent,0)==WAIT_TIMEOUT))