CloseHandle混淆 - 我必须在句柄的多个“副本”上调用CloseHandle吗?

时间:2010-12-03 09:39:13

标签: c++ windows winapi handle

我有一些(更多)关于调用CloseHandle的问题。

所以,the SO citizens have spoken, and you must always close a handle

问题1

我在析构函数中编写了以下代码片段:

HANDLE handles[] = { m_hGrabberThread, m_hCtrlThread, m_hErrDispatchThread  };
int nNumHandles = sizeof(handles) / sizeof(handles[0]);

for( int n = 0; n < nNumHandles; n ++ )
    CloseHandle( handles[n] );

以上代码是否有效,或者我必须分别对每个句柄成员变量调用CloseHandle()吗?

e.g。

if( m_hCtrlThread != INVALID_HANDLE_VALUE )
    CloseHandle( m_hCtrlThread );

我认为这个问题与问题2(含糊地)有关......

问题2

我有一个创建事件句柄的类:

HANDLE hEventAbortProgram = CreateEvent( NULL, TRUE, FALSE, NULL );

此句柄在其他对象的其他线程中共享。

通过分享句柄,我的意思是:

objectB.m_hEventAbort = objectA.m_hEventAbort;

每个对象的线程将执行以下操作:

while( WaitForSingleObject(m_hEventAbort, 0) == WAIT_TIMEOUT ) {...}

当发出事件信号时,所有线程都将退出。

我的问题是:我必须在句柄的每个副本上调用CloseHandle,还是只在我的主“父”对象中调用一次?

我想我要问 - 复制时是否计算了句柄参考?

我知道句柄只是一个void *的typedef,所以我的直觉说不,我只需要每个句柄调用一次。

2 个答案:

答案 0 :(得分:2)

问题2:对CloseHandle的调用次数应该平衡处理创建函数的调用次数。 如果只是将句柄分配给另一个HANDLE变量,则表示尚未创建新句柄 - 两个句柄具有相同的值。 您可以根据需要共享句柄值,但只有一个对象必须最终关闭句柄。

如果不能保证共享句柄的对象的销毁顺序;您可以使用DuplicateHandle从现有句柄创建其他句柄。创建的每个附加句柄都需要关闭,句柄引用的底层对象只有在所有句柄都关闭时才会被释放。

答案 1 :(得分:0)

回答1 您的上述代码有效。但是我建议你检查当前索引下的句柄是否是一个有效的句柄。

回答2 如果您正在共享此句柄而没有重复且没有参考计数等等,您只需要将其关闭一次并且它将无效。