1

(Win32 api で動作し、VS2010 の C 環境で)

私は2スレッドアプリを持っています。最初のスレッドは 2 番目のスレッドを fork し、指定された間隔 (「TIMEOUT」) の間待機してから、それを呼び出しますTerminateThread()。一方、2 番目のスレッドは を呼び出しますNetServerEnum()

正常に返されたかどうかにかかわらず、タイムアウトに達するとNetServerEnum、最初のスレッドがデッドロックされるようです。NetServerEnum独自のワーカースレッドを作成することはすでに気づいています。

最終的に、これらのスレッドの 1 つがデッドロックになり、通常は でntdll.dll!RtlInitializeExceptionChainプロセスを正常に終了できなくなります。

4

1 に答える 1

0

これはコメントには長すぎるので:

MSDNの逐語的な回答フォームを使用させてください (強調は私が行います):

TerminateThread は、最も極端な場合にのみ使用する必要がある危険な関数です。TerminateThread を呼び出す必要があるのは、ターゲット スレッドが何を行っているかを正確に把握しており、ターゲット スレッドが終了時に実行している可能性のあるすべてのコードを制御している場合のみです。たとえば、TerminateThread は次の問題を引き起こす可能性があります。

  • ターゲット スレッドがクリティカル セクションを所有している場合、クリティカル セクションは解放されません。
  • ターゲット スレッドがヒープからメモリを割り当てている場合、ヒープ ロックは解放されません。* ターゲット スレッドが終了時に特定の kernel32 呼び出しを実行している場合、スレッドのプロセスの kernel32 状態が矛盾する可能性があります。
  • ターゲット スレッドが共有 DLL のグローバル状態を操作している場合、DLL の状態が破壊され、DLL の他のユーザーに影響を与える可能性があります。

これを読むと、システム コールでスタックしているスレッドをキャンセル (終了) することがなぜ悪い考えなのかが簡単に理解できます。


OP の設計に対する可能な代替アプローチは、スレッドの呼び出しを生成しNetServerEnum()、システム コールが返されるまで単純に実行させることです。

その間、メイン スレッドは、たとえばネットのスキャンに予想より時間がかかることをユーザーに通知するなど、他のことを行うことができます。

于 2013-06-12T17:01:22.027 に答える