次の点を考慮してください。
void SomeClass::associateCompletionPort(HANDLE hJob) {
JOBOBJECT_ASSOCIATE_COMPLETION_PORT jacp = { 0 };
jacp.CompletionKey = hJob;
jacp.CompletionPort = hCompletionPort;
if (!SetInformationJobObject(
hJob,
JobObjectAssociateCompletionPortInformation,
&jacp,
sizeof(jacp))) {
// open a 'pop-up' with an error message, of the last error encountered.
dumpLastError(TEXT("SetInformationJobObject"));
}
}
1.hCompletionPort
のコンストラクターでSomeClass
、次のように初期化されます。
SomeClass::SomeClass() :
hCompletionPort(CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1)) {
if (!hCompletionPort) {
dumpLastError(TEXT("CreateIoCompletionPort"));
}
}
2.hJob
プロセスを 1 つだけ「含む」ジョブ オブジェクトへのハンドルです。3.このメソッドは複数のジョブ オブジェクトに対して呼び出されるため、ジョブを完了ポートに関連付ける際には 1 対多のマッピングが存在します。
注:これは、後で特定の制限を超えたり破ったりするたびにメッセージを取得するために使用するコードの一部です。
この特定のスニペットが実行される前に、問題のプロセス (それぞれ 1 つのジョブ オブジェクトに限定されます) を起動して、これをテストします。
問題:
ジョブ オブジェクトが完了ポートに関連付けられるたびに、関連付けは次のエラーで失敗します。
SetInformationJobObject がエラー 87 で失敗しました。パラメータが正しくありません。
しかし、最も厄介なことは、まれに、すべてが正常に機能することです。これを確認できるのは、コードの他の部分で期待していたメッセージが表示されるためですGetQueuedCompletionStatus
。
たとえば、数時間前にこれを初めて実行したとき、すべてが期待どおりに機能しました。しかし、その後は常に同じエラー メッセージが表示され、もちろん、制限が破られているというメッセージをキャッチすることはありませんでした。