2009-04-01 14 views
2

に私はここで説明のThreadPool、QueueUserWorkItemとデッドロックがシャットダウン

Allen Bauer on thread pools

非常に単純な実装のようなスレッドプールを実装し、正常に動作しませんが、私のアプリケーションはもはやシャットダウンします。私はQueueUserWorkItemのヘルプ項目で使用される(WinAPIの関数の中でIOの完了について何かを読んだことを覚え機能に

ntdll.ZwRemoveIoCompletion 

を突っ込ん2つのワーカースレッドという(他1つのスレッド、私はキューイングスレッドを推測する)ようですスレッドプールの実装)、私はそれを正しく理解できませんでした。私はWT_EXECUTELONGFUNCTIONをワーカースレッドに使用しました。実行には時間がかかることがあり、既存のワーカースレッドが終了するのを待たずに、新しいワーカースレッドを作成します。ワーカースレッドに割り当てられたタスクの中には、I/O処理を実行するものがあります。私はWT_EXECUTEINIOTHREADを使用しようとしましたが、それは役に立たないようです。

私は、コールスタックwithtクリティカルセクションは、私がここで間違ってやっている

System.Halt0, System.FinalizeUnits, Classes.Finalization, TThread.Destroy, 
RtlEnterCriticalSection, RtlpWaitForCriticalSection 

任意のアイデアであることにエントリのメインスレッドが待機することを言及する必要がありますか?あなたの助けを前もってありがとう。

+0

詳細なコールスタックを取得する必要がありますか?間違いなくTThread.DestroyとRtlEnterCriticalSectionの間に何かがありません。 – Alex

答えて

0

ワーカースレッドがシャットダウンしていることを確認するには、空のIO完了ポートで待機しているときに何らかの方法で起床する必要があります。最も簡単な方法は、何らかの種類のNULLメッセージをポートにポストすることであるように見えます。それは、これを整然とした方法で停止するシグナルとして扱うべきです。

+0

私はこれをどうやってもっと詳しく説明できますか?ありがとう! – jpfollenius

+0

私は、PostQueuuedCompletionStatusが行く方法かもしれないと考えましたが、完了ポートハンドルを取得する方法がわかりません。誰でも? – jpfollenius

+0

IO完了ポート機能のあるレベルのラッパーであるQueueUserWorkItemを使用しています。ワーカースレッドをシャットダウンするという意味のユーザーワークアイテムをキューに入れることができます。 –

0

再度入力する前にクリティカルセクションから退出する必要があります。だから問題はロックの中にある。他のスレッドで

EnterCriticalSection(SomeCriticalSection); 
sort code... 
LeaveCriticalSection(SomeCriticalSection); 

:いくつかのスレッドで

EnterCriticalSection(SomeCriticalSection); 
clean up code... 
LeaveCriticalSection(SomeCriticalSection); 

ソートコードは最初のスレッドで実行されている第二のスレッドがクリーンアップコードをもう一度を実行しようとした場合スレッドは、ソートコードが終了してクリティカルセクションを離れるまで待機します。クリティカルセクションを離れると、同じクリティカルセクションを入力することができます。デッドロックコードが重要なセクションの内側にあるため、デッドロックコードの絞り込みに役立つことを願っています。

完了ポートは、あなたがそれはあなたが完了ポートを作成するときにハンドルの保存することができますハンドルを取得するには、次の

FIoCPHandle := CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0 , 0, FNumberOfConcurrentThreads); 
+0

ヒントをお寄せいただきありがとうございます。私はまだ調査中です。完了ポートハンドルについて:明示的に作成するのではなく、すべての作業を行うQueueUserWorkItemを使用するので、ハンドルはありません。 – jpfollenius

0

限り、ワーカースレッドがスレッドプールに戻されたとして、QueueUserWorkItemを使用している場合、あなたはいけませんそれらを閉鎖するために何かをしなければならない。スレッドプールのWT_EXECUTEDEFAULTコンポーネントは、作業項目をI/O完了ポートにキューイングします。このポートはスレッドプールの内部実装の一部であり、アクセスすることはできません。

スタックされていると思われるスレッドに対して、より詳細なコールスタックを提供できますか?この問題は、診断するのがはるかに簡単になります。

関連する問題