情况一:HANDLE hThread = NULL;
UINT __stdcall Fun(LPVOID pParam) 
{
ASSERT(CloseHandle(hThread));
Sleep(5000);
return 0;
}unsigned int threadID;
hThread = (HANDLE) _beginthreadex(NULL, 0, Fun, NULL, 0, &threadID);
WaitForSingleObject(hThread, INFINITE);
结果是:WaitForSingleObject等待5秒(CloseHandle调用是成功的)情况二:HANDLE hThread = NULL;
UINT __stdcall Fun(LPVOID pParam) 
{
Sleep(5000);
return 0;
}unsigned int threadID;
hThread = (HANDLE) _beginthreadex(NULL, 0, Fun, NULL, 0, &threadID);
ASSERT(CloseHandle(hThread));
WaitForSingleObject(hThread, INFINITE);
结果是:WaitForSingleObject不等待(CloseHandle调用是成功的)情况三:HANDLE hThread = NULL;
UINT __stdcall Fun(LPVOID pParam) 
{
Sleep(5000);
return 0;
}unsigned int threadID;
hThread = (HANDLE) _beginthreadex(NULL, 0, Fun, NULL, 0, &threadID);
WaitForSingleObject(hThread, INFINITE);
结果是:WaitForSingleObject等待5秒(没有调用CloseHandle)经过上面的测试,我有点发晕了,到底CloseHandle会不会对WaitForSingleObject产生影响,在什么情况下产生影响,产生什么样的影响?

解决方案 »

  1.   

    情况一
      这种情况 WaitForSingleObject 在 CloseHandle 前调用, WaitForSingleObject  会等待线程结束, CloseHandle 不会影响
    情况二
      WaitForSingleObject 的Handle被Close, Handle无效, 所以WaitForSingleObject 调用失败, 所以没等待
    情况三
      一般用法
      

  2.   

    仅仅CloseHandle不能使线程句柄处于信号状态,必须线程退出才能激活信号。
      

  3.   

    看看windows核心编程就知道,内核对象
      

  4.   

    CloseHandle 只是对线程句柄技术减1,需要等线程执行完了
      

  5.   

    to zzz3265
    你说:
    情况一 
      这种情况 WaitForSingleObject 在 CloseHandle 前调用, WaitForSingleObject  会等待线程结束, CloseHandle 不会影响 那如果WaitForSingleObject 在 CloseHandle 之后调用呢?是不是CloseHandle 就会影响到WaitForSingleObject了呢?我将情况一改为如下,可是CloseHandle 仍然影响不了WaitForSingleObject,如下:
    HANDLE hThread = NULL;
    UINT __stdcall Fun(LPVOID pParam) 
    {
        Sleep(5000);
        ASSERT(CloseHandle(hThread));
        Sleep(5000);
        return 0;    
    }unsigned int threadID;
    hThread = (HANDLE) _beginthreadex(NULL, 0, Fun, NULL, 0, &threadID);
    WaitForSingleObject(hThread, INFINITE);
    结果是等待了10秒,这又是为什么呢?
      

  6.   

    我是问,在情况一中,在线程里面CloseHandle,为什么没有影响到主线程里面的WaitForSingleObject,我觉得至少能让WaitForSingleObject因为错误(句柄无效)而返回才对啊!
    而在情况二中:主线程自己调用CloseHandle,再调用WaitForSingleObject,就可以得到一个错误(句柄无效)。
      

  7.   

    注意,我已经把情况一改成如下了:
    HANDLE hThread = NULL;
    UINT __stdcall Fun(LPVOID pParam) 
    {
        Sleep(5000);
        ASSERT(CloseHandle(hThread));
        Sleep(5000);
        return 0;    
    }unsigned int threadID;
    hThread = (HANDLE) _beginthreadex(NULL, 0, Fun, NULL, 0, &threadID);
    WaitForSingleObject(hThread, INFINITE);
    这样做的目的是在WaitForSingleObject之后调用CloseHandle,可能WaitForSingleObject仍然等待了10秒!即等待到线程结束。
      

  8.   


    这样 WaitForSingleObject  也在 CloseHandle 前调用, 跟情况一一样你这样试试HANDLE hThread = NULL;
    UINT __stdcall Fun(LPVOID pParam) 
    {
        ASSERT(CloseHandle(hThread));
        Sleep(15000);
        return 0;    
    }unsigned int threadID;
    hThread = (HANDLE) _beginthreadex(NULL, 0, Fun, NULL, 0, &threadID);
    Sleep(5000);
    WaitForSingleObject(hThread, INFINITE);
      

  9.   

    你的意思是,如果WaitForSingleObject已经在等待的时候,调用CloseHandle不会影响到它?
    这是为什么呢?
      

  10.   

    CloseHandle,,只是告诉操作系统我们已经对进程中的统计数据不感兴趣
      

  11.   


    系统或程序自身的机制问题, 举个简单的例子CHAR  szName[] = "xvsdfd";
    CHAR * pStr;pStr = szName; //等效 OpenHandle, 用句柄访问对象
    printf("%s", pStr); //使用句柄访问对象,类似WaitForSingleObjectpStr = NULL; //等效 CloseHandlepStr = NULL; 与 printf("%s", pStr); 这俩句前后不一样, 结果就会不一样
      

  12.   

    关于Handle和WaitForSingleObject的关系,我说说我自己的理解:首先要先理解什么叫内核对象和内核对象的几个重要的特性。
    下面是window内核编程的原文:系统要创建和操作若干类型的内核对象,比如存取符号对象、事件对象、文件对象、文件映射对象、I/O完成端口对象、作业对象、信箱对象、互斥对象、管道对象、进程对象、信标对象、线程对象和等待计时器对象等。这些对象都是通过调用函数来创建的。例如,CreateFileMapping函数可使系统能够创建一个文件映射对象。每个内核对象只是内核分配的一个内存块,并且只能由该内核访问。该内存块是一种数据结构,它的成员负责维护该对象的各种信息。有些数据成员(如安全性描述符、使用计数等)在所有对象类型中是相同的,但大多数数据成员属于特定的对象类型。例如,进程对象有一个进程ID、一个基本优先级和一个退出代码,而文件对象则、拥有一个字节位移、一个共享模式和一个打开模式。特性:内核对象的使用计数,安全性等。这里我们讨论到的是关于他的使用计数这个特性。内核知道有多少进程正在使用某个内核对象,因为每个对象包含一个使用计数。使用计数是所有内核对象类型常用的数据成员之一。当一个对象刚刚创建时,它的使用计数被置为1。然后,当另一个进程访问一个现有的内核对象时,使用计数就递增1。当进程终止运行时,内核就自动确定该进程仍然打开的所有内核对象的使用计数。如果内核对象的使用计数降为0,内核就撤消该对象。这样可以确保在没有进程引用该对象时系统中不保留任何内核对象。
    ------------------------------------------
    如果在WaitForSingleObject之前CloseHandle了,这样系统会撤销这个对象,这样handle已经失效。所以再wait的话已经是无效的handle了。如果是之后CloseHandle为什么不会有影响呢,因为WaitForSingleObject会使计数+1达到2,CloseHandle只是将这个计数-1而已,这样内核对象计数还有1,这样这个handle还是有效的,所以这时再CloseHandle就还不会有影响。并且的WaitForSingleObject退出的时候也应该会有CloseHandle这样的操作的。这个应该和COM中AddRef和Release这个两个函数非常像。
      

  13.   

    只要弄清楚下面的东西就知道1和2的区别了
    1. 对于内核对象,系统会维护一个引用计数,
    2. 对于每个进程,进程本身维护了一个句柄表,记录它可以操作的内核对象在本进程内的映射值(就是句柄)
    3. CloseHandle会删除内核对象的一个引用计数,同时会删除进程句柄表中的一项(如果该句柄在进程内再无引用)
    4. WaitForSingleObject对传进来的句柄首先执行的动作就是查进程的句柄表,如果不存在这一项,返回无效句柄错误这样解释应该很清楚了吧
    在情况1里WaitForSingleObject在CloseHandle前调用,这个使用hThread还在进程句柄表里
    情况2里CloseHandle先一步把进程句柄表里的hThread这一项删掉了,再去WaitForSingleObject当然找不到句柄了
      

  14.   

    CloseHandle;只是把内核对象的计数-1,因为内核对象也是需要内存的,内核对象只是存放一些信息,对信息不再感兴趣的时候,就把那块内存释放掉,但线程还是要执行完的
      

  15.   

    CloseHandle;只是把内核对象的计数-1,因为内核对象也是需要内存的,内核对象只是存放一些信息,对信息不再感兴趣的时候,就把那块内存释放掉,但线程还是要执行完的