DllGetClassObjectエントリ ポイントでカスタム ロガーを初期化し、オーバーライドされたExitInstance関数でこのロガーを初期化解除する COM/ATL dll があります。ロガーは、定期的にバッファをチェックし、すべてのレコードをすばやくログに記録する別のスレッドとして実装されます。
さて、問題です。ご存知のように、Windows は定期的に未使用の COM dll をチェックしてアンロードします。dll のアンロード プロセス中にロガー スレッドが終了するのを待ちたいのですが、正しい方法がわかりません。私はいくつかの解決策を試しました:
WaitForSingleObjectを使用して、ロガー スレッドが完了するまで待ちます。メイン スレッドがDllMain関数内にあるため、これは機能しません。
カスタム イベントを作成し、ロガー スレッドが終了する直前に発生させます。
SetEvent(_loggerExitEvent); // can be blocked here! return 0;
このコード ブロックはアトミックではないため、これも機能しません。ロガー スレッドはイベントを発生させ、dll がメモリからアンロードされるまでブロックされ、その後再びウェイクアップして厄介なアクセス違反エラーを生成するだけです。
ロガー スレッドが返されることを 100% 確信している場合は、上記のイベントを受け取った後にTeminateThreadを使用します。これは非常に不安定です。
メイン スレッドをループして、ロガー スレッドのステータスを定期的にチェックします。
while(TRUE == ::GetExitCodeThread(_loggerThread, &loggerThreadExitCode) && loggerThreadExitCode== STILL_ACTIVE) { Sleep(100); }
非常に汚れていて不安定です。GetExitCodeThreadが FALSE を返すとどうなりますか?
それで、問題は、dllのアンロードプロセス中に別のスレッドが完了するのを待つ正しい方法があるということですか? または、私は何か完全に間違っていますか?