上一次问线程的句柄问题有哥们回帖:
CloseHandle释放的是线程内核对象,并不是将线程停止,所以用了CloseHandle之后,你不能再用这个内核对象进行相关的操作,但是线程本身还会运行。 
这里所说的加1减1是指对线程内核对象的引用值加1。不要将线程内核对象与线程混为一谈

我对“线程本身还会运行”很怀疑,因为线程执行完计数-1,计数器才可能达到0,也就是线程执行完了才可能释放线程内核对象问题2:对于一个普通的HANDLE 文件、管道、邮槽……
(1)HANDLE hXX;这时hXX的内核对象的计数器是多少?
(2)hXX=CreatePipe…… 这时内核对象的计数器是多少?
经历了以上2步后调用CloseHandle(hXX);
(3)hXX = NULL;这时计数器是多少?给一个句柄赋值NULL会引起对应内核对象计数器变化吗?

解决方案 »

  1.   

    问题1,如果你不相信,可以自己用程序验证一下。
    问题2,HANDLE是一种数据类型,可以用来储存句柄值,也就是内核对象的索引值。就像一个int变量可以作为数组的下标,但不能把int变量看作数组元素一样。
    (1)HANDLE hXX,这是定义HANDLE型变量hXX,并未给hXX赋值,该变量值无意义。
    (2)hXX=CreatePipe,如果创建成功,内核对象计数器是1;如果失败,则没有分配内核对象。
    (3)hXX = NULL,给变量赋值为NULL,即为空,此后hXX不是有效的句柄值,也不代表任何内核对象。给HANDLE型变量赋值只会应该该变量,不会影响到变量原值对应的内核对象。
      

  2.   

    我正在学孙鑫教程的命名管道部分  程序说明:
    在CNamedPipeSrvView中+一个句柄hPipe在构造函数中:
    CNamedPipeSrvView::CNamedPipeSrvView()
    {
    // TODO: add construction code here
    hPipe=NULL;//第一次
    }
    在创建管道是用上
    void CNamedPipeSrvView::OnPipeCreate() 
    {
    // TODO: Add your command handler code here
    hPipe=CreateNamedPipe("\\\\.\\pipe\\MyPipe",
    PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
    0,1,1024,1024,0,NULL);//第二次
    if(INVALID_HANDLE_VALUE==hPipe)
    {
    MessageBox("创建命名管道失败!");
    hPipe=NULL;
    return;
    }
    HANDLE hEvent;
    hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
    if(!hEvent)
    {
    MessageBox("创建事件对象失败!");
    CloseHandle(hPipe);//可能的第三次
    hPipe=NULL;//这里行的通吗?
    return;
    }
    OVERLAPPED ovlap;
    ZeroMemory(&ovlap,sizeof(OVERLAPPED));
    ovlap.hEvent=hEvent;
    if(!ConnectNamedPipe(hPipe,&ovlap))
    {
    if(ERROR_IO_PENDING!=GetLastError())
    {
    MessageBox("等待客户端连接失败!");
    CloseHandle(hPipe);
    CloseHandle(hEvent);
    hPipe=NULL;
    return;
    }
    }
    if(WAIT_FAILED==WaitForSingleObject(hEvent,INFINITE))
    {
    MessageBox("等待对象失败!");
    CloseHandle(hPipe);
    CloseHandle(hEvent);
    hPipe=NULL;
    return;
    }
    CloseHandle(hEvent);
    }
    最后析构函数中CNamedPipeSrvView::~CNamedPipeSrvView()
    {
    if(hPipe)
    CloseHandle(hPipe);
    }
      

  3.   

    (3)hXX = NULL,给变量赋值为NULL,即为空,此后hXX不是有效的句柄值,也不代表任何内核对象。给HANDLE型变量赋值只会应该该变量,不会影响到变量原值对应的内核对象。这个明白了,计数器不会+
      

  4.   

    四五个问题看得我头晕用HANDLE操作对象就行了, 管计数器干嘛?
      

  5.   

    create/open系列创建/打开局柄的函数计数+1, closehandle计数-1hHandle = NULL的写法仅仅用于防止你后续的代码错误调用已释放的局柄而已,在vc中对对象实际没有任何作用。vb/javascript/C#等倒是使用该方法释放对象引用。
      

  6.   

    现在就剩一核心问题了:hPipe=CreateNamedPipe("\\\\.\\pipe\\MyPipe", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0,1,1024,1024,0,NULL);函数失败时返回INVALID_HANDLE_VALUE  这个时候对应内核对象计数器+1没