我有代码创建一个线程,并在程序结束时用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 );
....
}
但为什么我需要关闭手柄呢?如果我不这样做会怎么样?
答案 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关闭。