18

最近、このタイトルで言及したように、この問題に遭遇しました。QThread::terminate() を使用してみましたが、デッド ループにあるスレッドを停止できません (たとえば、while(1))。

どうもありがとう。

4

5 に答える 5

12

スレッドを終了することは、非同期操作を停止するための簡単な解決策ですが、通常は悪い考えです。スレッドがシステム コールを実行しているか、終了時にデータ構造を更新している最中である可能性があり、プログラムが終了する可能性があります。またはOSが不安定な状態にあることさえあります。

while(1) を while( isAlive() ) に変換し、スレッドを終了させたいときに isAlive() が false を返すようにしてください。

于 2009-12-14T09:28:21.203 に答える
1

QThreads は、終了時に「自然に」終了するとデッドロックする可能性があります。

たとえば、Unix では、スレッドが「読み取り」呼び出しを待機している場合、終了試行 (Unix シグナル) により、スレッドが破棄される前にエラー コードで「読み取り」呼び出しが中止されます。

これは、スレッドが終了している間も、スレッドが自然な終了点に到達できることを意味します。その場合、一部の内部ミューテックスが「終了」呼び出しによってすでにロックされているため、デッドロックに達します。

私の回避策は、スレッドが終了した場合にスレッドが戻らないようにすることです。

while( read(...) > 0 ) {

  // Do stuff...
}

while( wasTerminated )
  sleep(1);

return;

ここでのwasTerminatedは、アトミック int を使用して、実際にはもう少し複雑に実装されています。

enum {

  Running, Terminating, Quitting
};

QAtomicInt _state; // Initialized to Running

void myTerminate()
{
  if( _state.testAndSetAquire(Running, Terminating) )
    terminate();
}

void run()
{
  [...]

  while(read(...) > 0 ) {

    [...]
  }

  if( !_state.testAndSetAquire(Running, Quitting) ) {
    for(;;) sleep(1);
  }
}
于 2011-12-29T12:06:37.390 に答える
0

スレッドは を呼び出しましたQThread::setTerminationEnabled(false)か? これにより、スレッドの終了が無期限に遅延します。

編集:あなたが使用しているプラ​​ットフォームはわかりませんが、QThread::terminate の Windows 実装を確認しました。スレッドが最初から実際に実行されていて、上記の関数によって終了が無効にされていないと仮定すると、これは基本的にTerminateThread()Windows API のラッパーです。この関数は、どのスレッドからの軽視も受け入れず、リソース リークや同様のダングリング状態で混乱を残す傾向があります。スレッドを強制終了していない場合は、ゾンビ カーネル コール (ブロックされた I/O の可能性が最も高い) を扱っているか、どこかでさらに大きな問題が発生しています。

于 2009-12-14T03:53:53.833 に答える
0

名前のないパイプを使用するには

int gPipeFdTest[2];  //create a global integer array

パイプを作成するときに使用する場所として

if( pipe(gPipeFdTest) < 0)

{

perror("Pipe failed");

exit(1);

}

上記のコードは、読み取り用の gPipeFdTest[0] と書き込み用の gPipeFdTest[1] の両端を持つパイプを作成します。あなたができることは、選択システムコールを使用してパイプを読み取るように設定された実行機能です。そして、走り出したいところから、write システムコールを使って書き込む設定をします。実装に適しているため、パイプの読み取り側を監視するためにselectシステムコールを使用しました。あなたのケースでこれらすべてを理解してみてください。さらにサポートが必要な場合は、バズをください。

編集:

私の問題はあなたの問題と同じでした。私は while(1) ループを持っていて、私が試した他のことにはミューテックスや他の派手なマルチスレッドマンボジャンボが必要でした.これは複雑さを増し、デバッグは悪夢でした. パイプを使用すると、コードが単純化されるだけでなく、これらの複雑さから解放されます。これが最良の選択肢であると言っているわけではありませんが、私の場合、最良かつ最もクリーンな代替手段であることが判明しました。この解決策の前に、ハングしたアプリケーションにバグがありました。

于 2010-01-09T12:50:43.387 に答える
0

exitまたはquitを試しましたか?

于 2009-12-14T02:27:37.143 に答える