2

ここで説明するようなスレッドプールを実装しました

スレッドプールのAllenBauer

非常に単純な実装で、正常に動作しますが、アプリケーションがシャットダウンしなくなりました。2つのワーカースレッド(および他の1つのスレッド、キューイングスレッド)が関数でスタックしているようです

ntdll.ZwRemoveIoCompletion

QueueUserWorkItem(スレッドプールの実装で使用されるWinAPI関数)のヘルプエントリでIOの完了について何か読んだことを覚えていますが、正しく理解できませんでした。実行に時間がかかる可能性があり、既存のワーカースレッドが終了するのを待つのではなく、新しいワーカースレッドを作成する必要があるため、ワーカースレッドにWT_EXECUTELONGFUNCTIONを使用しました。ワーカースレッドに割り当てられたタスクの一部は、I/O処理を実行します。WT_EXECUTEINIOTHREADを使用しようとしましたが、役に立たないようです。

メインスレッドは、コールスタックが存在しないクリティカルセクションへのエントリを待機していることに注意してください。

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

私がここで間違っていることについて何か考えはありますか?よろしくお願いします。

4

3 に答える 3

0

ワーカー スレッドが確実にシャットダウンされるようにするには、ワーカー スレッドが空の IO 完了ポートで待機している場合に、何らかの方法でそれらを起動する必要があります。最も簡単な方法は、ある種の NULL メッセージをポートに送信することです。これを、正常に停止するためのシグナルとして処理する必要があります。

于 2009-04-01T08:55:56.893 に答える
0

再び入る前に、クリティカル セクションから退出する必要があります。したがって、問題はロックの内部にあります。

いくつかのスレッドで:

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

他のスレッドで:

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

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

完了ポート ハンドルを取得するには、完了ポートを作成するときにそのハンドルを保存できます。

FIoCPHandle := CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0 , 0, FNumberOfConcurrentThreads);
于 2009-04-02T11:38:37.477 に答える
0

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

スタックしているように見えるスレッドの詳細なコール スタックを提供していただけますか? これにより、この問題の診断がはるかに容易になります。

于 2009-12-11T07:33:39.420 に答える