我需要调用CloseHandle吗?

时间:2015-09-01 17:10:58

标签: c++ visual-c++

我有代码创建一个线程,并在程序结束时用CloseHandle关闭它。

int main()
{
....

    HANDLE   hth1;
    unsigned  uiThread1ID;

    hth1 = (HANDLE)_beginthreadex( NULL,         // security
                                   0,            // stack size
                                   ThreadX::ThreadStaticEntryPoint,
                                   o1,           // arg list
                                   CREATE_SUSPENDED,  // so we can later call ResumeThread()
                                   &uiThread1ID );
....
CloseHandle( hth1 );

....

}

但为什么我需要关闭手柄呢?如果我不这样做会怎么样?

5 个答案:

答案 0 :(得分:2)

  

但为什么我需要关闭处理?

句柄是占用内核和用户空间内存的有限资源。保持句柄活动不仅需要整数值的存储,而且还意味着内核必须保留线程信息(例如用户时间,内核时间,线程ID,退出代码),并且它不能回收线程ID,因为您可以使用该句柄查询它 因此,最好在不再需要时关闭句柄。

这是你根据API合约要做的事情(但当然你可以违反合同)。

  

如果我不这样做会怎么样?

嗯,老实说......没什么。您将泄漏该句柄,但对于一个句柄,影响将无法衡量。当您的进程退出时,Windows将关闭句柄。

但是,在正常情况下,您应该关闭不再需要的句柄,就像释放已分配的内存一样(即使操作系统在您的进程退出时也会释放它)。

虽然甚至可以将其视为“优化”而不是明确释放资源,但为了拥有正确的程序,应该始终这样做。正确性优先,优化第二 此外,您越早释放资源(无论它有多小),它就越早再次供系统重用。

答案 1 :(得分:1)

在这里,您有一个主题可以回答您的问题: Can I call CloseHandle() immediately after _beginthreadex() succeeded?

问候。

答案 2 :(得分:1)

是的,您需要在某个时刻关闭句柄,否则您将泄漏有限的OS资源。

答案 3 :(得分:0)

我可以建议为你的手柄创建一个RAII包装器吗?基本上你编写了一个包装器来存储你创建的句柄,并在它的析构函数中调用CloseHandle。这样你永远不必担心记住关闭它(当它超出范围时会自动关闭)或者如果在打开手柄和关闭它之间发生异常则泄漏句柄。

答案 4 :(得分:0)

如果您不关闭手柄,它将保持打开状态,直到您的过程终止。根据手柄后面的内容,这可能很糟糕。资源通常与句柄相关联,在程序终止之前,这些资源不会被清除;如果你只使用一些手柄,那么这些手柄恰好是轻巧的。那真的不重要。其他句柄(如文件句柄)具有其他副作用,可以保持句柄打开,例如锁定打开的文件,直到您的进程退出。这对用户或其他应用程序来说非常烦人。

一般情况下,最好清理所有句柄,但在此过程结束时,所有句柄都会被Windows关闭。

相关问题