3

クロスプラットフォーム プロジェクトでスレッド ローカル ストレージを利用する必要があります。*IX では pthreads を使用しており、 の 2 番目の引数として渡される素敵なデストラクタ関数ポインタのおかげでメモリ リークを回避できますpthread_key_createが、WindowsTlsAllocではそのようなことはありません。また、スレッドの終了時に関数が呼び出される一般的な場所を見つけることもできません (それ以外の場合は、終了時に呼び出される関数ポインターのリストを自作します)。

現状では、スレッドローカルストレージを実際に使用するには、ヒープに独自のスペースを割り当ててへのポインターを渡す必要があるという状況が基本的にあるようですがTlsSetValue、スレッドが終了した場合...私には保証する方法がありませんメモリが解放されました (誰かが明示的に呼び出しTlsGetValueている場合と、スレッド関数の最後に // /etc がある場合を除きますdeletefreeHeapFree

誰かがより良い方法を知っていますか?

4

2 に答える 2

4

スレッドが終了した場合でも、スレッド固有のリソースを取り除くための優れた「ファイナライザー」を入手できます。スレッドのハンドルのコピーを(経由して)RegisterWaitForSingleObject待機するために使用します-複製されたハンドルを使用する必要があります。待機はハンドル{しゃれを意図していない}の終了を処理できません。 ヒープに割り当てられた構造/レコードを使用して、ファイナライズされたリソース、待機中のハンドル、および待機ハンドル自体を保持します。これにより、ファイナライザーは、ファイナライズされたスレッドではなく、システムスレッドプールで実行されます(この時点ですでに停止しています)。そして、ファイナライザーをファイナライズすることを忘れないでください:)DuplicateHandle

于 2010-07-14T10:02:25.773 に答える
3

DLL ( ) のエントリ ポイントはDLLmain、理由コード のスレッド終了時に呼び出されますDLL_THREAD_DETACH。スレッドの終了時に呼び出す関数を追跡する DLL を作成するのは非常に簡単です。

または、Boost.Threadと関数を使用してboost::this_thread::at_thread_exit、スレッドの終了時に呼び出される関数を登録するかboost::thread_specific_ptr、TLS の使用を完全にラップするために使用します。

于 2010-07-13T22:04:11.927 に答える