2010-12-03 32 views
0

私はCloseHandleを呼び出すことに関していくつか(もっと)質問があります。CloseHandleの混乱 - ハンドルの複数の "コピー"で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()を呼び出す必要があります?

私はこの質問を2に疑問を(漠然と)リンクされているとし
if(m_hCtrlThread != INVALID_HANDLE_VALUE) 
    CloseHandle(m_hCtrlThread); 

...

質問2

私はイベントハンドルを作成するクラスがあります。

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

このハンドルは、他のオブジェクト内の他のスレッド間で共有されます。

は、ハンドルを共有することによって、私は意味:

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

イベントが通知され、すべてのスレッドが終了します:

objectB.m_hEventAbort = objectA.m_hEventAbort; 

各オブジェクトのスレッドは、その後のようなものを行います。

私の質問は、ハンドルの各コピーでCloseHandleを呼び出すか、メインの「親」オブジェクトで1回だけ呼び出す必要がありますか?

私は頼んでいると思います - コピーされたときに参照カウントがカウントされますか?

私はハンドルがvoid *のtypedefであることを知っています。したがって、私の本能はいいえ、ハンドルごとに一度呼び出す必要があります。

+0

「CloseHandle(INVALID_HANDLE_VALUE)」を呼び出すことが何らかの害を及ぼすのではないかと疑いがあります。 – ruslik

+1

http://stackoverflow.com/questions/1562421/making-a-handle-raii-compliant-using-shared-ptr-with-a-custom-deleterをご覧ください。 Boostを使って簿記をすることができるかもしれません。 ) – MSalters

答えて

2

質問2:CloseHandleの呼び出し回数は、作成関数を処理する呼び出しの数のバランスを取る必要があります。 ハンドルを別のHANDLE変数に割り当てるだけでは、新しいハンドルは作成されません.2つのハンドルは同じ値を持ちます。 ハンドルの値は必要なだけ共有できますが、1つのオブジェクトで最終的にハンドルを閉じる必要があります。

ハンドルを共有するオブジェクトの破壊順序を保証できない場合は、 DuplicateHandleを使用して、既存のハンドルから追加ハンドルを作成することができます。作成された追加のハンドルはすべて閉じなければなりません。ハンドルが参照する基本オブジェクトは、すべてのハンドルが閉じられたときにのみ解放されます。

0

回答1 上記のコードは有効です。しかし、私はあなたが現在のインデックスが有効なハンドルである "下"のハンドルを確認することをお勧めします。

回答2 あなたはそうで重複していないreferencカウントせずにこのハンドルを共有している場合、あなたはそれを一度閉じてする必要があり、それが無効になります。

+0

ポイント1に、ええ、それは唯一の擬似コードです) –

+1

?...ちょっとした提案^^ ...あなたの質問に答えますか?:) – Incubbus

+0

はい、ありがとうIncubbus! –

関連する問題