20

two からの入力をブロックするアプリケーションを作成していますistreams

どちらからistreamの読み取りも同期 (ブロッキング) 呼び出しであるため、Boost::thread読み取りを行うために 2 つの を作成することにしました。

これらのスレッドのいずれかが (受信した入力に基づいて) 「終了」に達することができ、「終了」に達すると、両方の入力ストリームの受信が停止します。残念ながら、どちらがそうするかはわかりません。

したがって、join()実際に返される (ブロック解除される) スレッドは 1 つだけ (どのスレッドかを事前に決定することはできません) であるため、両方のスレッドを使用することはできません。

どうにかしてもう一方を強制的に終了させる必要がありますが、入力を待ってブロックされているため、戻る時間だと判断できません(条件変数かどうか)。

次のいずれかへの方法はありますか?

  • boost::thread にシグナルを送信する、または
  • 強制的istreamに「失敗」させる、または
  • Boost::thread を殺す?

ノート:

  • その一つistreamscin
  • プロセスを再起動しようとしているため、リセットを禁止する方法で入力ストリームを閉じることはできません。

編集:

  • 「終わり」に達したとき、どのスレッドが正常に終了したか、どのスレッドを強制終了する必要があるかを知っています。それは私が理解する必要がある殺害です(またはistreamから読み取るための別の戦略)。
  • 終了して適切にクリーンアップするには、両方のスレッドが必要です:(

ありがとう!

4

9 に答える 9

4

ブースト スレッドが i/o 操作でブロックされている場合 (例: cin>>whatever)、boost::thread::terminate()スレッドを強制終了しません。 cini/o は有効な終了ポイントではありません。22 をキャッチします。

于 2011-11-08T18:26:57.900 に答える
4

はいあります!

boost::thread::terminate()あなたの仕様に合わせて仕事をします。

対象のスレッドが例外をスローします。キャッチされていないと仮定すると、スタックは適切に巻き戻され、すべてのリソースが破棄され、スレッドの実行が終了します。

終了は即時ではありません。(とにかく、その時点で間違ったスレッドが実行されています。)

これは事前定義された条件下で発生します。最も便利なのは、おそらく を呼び出すときでboost::this_thread::sleep();、そのスレッドに定期的に実行させることができます。

于 2010-12-06T04:37:47.387 に答える
4

クロスプラットフォームでそれを行う方法はないと思いますが、探しているのは pthread_cancel です。ブースト スレッドを使用すると、スレッドからnative_handleを取得し、それに対して pthread_cancel を呼び出すことができます。

さらに、より良い方法は、複数のファイルに対する select 呼び出しに相当する boost asioを使用することです。そうすれば、1 つのスレッドが入力を待ってブロックされますが、いずれかの入力ストリームから来る可能性があります。ただし、iostream を使用してこのようなことを行うのがどれほど簡単かはわかりません。

于 2008-11-07T17:11:21.810 に答える
1

Linuxでは、IOのブロックを中断するため、pthread_signal(SIGUSR1)を使用します。コードを移植したときに発見したようなWindowsへの呼び出しはありません。ソケット読み取り呼び出しで非推奨になったもののみ。Windowsでは、ブロッキング呼び出しを中断するイベントを明示的に定義する必要があります。したがって、ブロッキングIOを中断する一般的な方法のようなもの(AFAIK)はありません。

boost.threadデザインは、明確に識別された割り込みポイントを管理することによってこれを処理します。boost.asioはよくわかりませんが、とにかく頼りたくないようです。非ブロッキングパラダイムを使用するようにリファクタリングしたくない場合は、非ブロッキング(ポーリング)とブロッキングIOの間に何かを使用することができます。それは(擬似コード?)のようなことをします:

while(!stopped && !interrupted)
{
    io.blockingCall(timeout);
    if(!stopped && !interrupted)
    {
        doSomething();
    }
}

次に、2つのスレッドを中断して、それらを結合します...

おそらくあなたの場合はもっと簡単ですか?一方のスレッドが終了したことを知っているマスタースレッドがある場合は、もう一方のスレッドのIOを閉じる必要がありますか?

編集:ところで、私はあなたが持っている最終的な解決策に興味があります...

于 2009-07-15T15:06:03.107 に答える
1

私自身も同様の問題を抱えており、この解決策に到達しました。この質問の他の読者が役立つかもしれません。

wait() コマンドで条件変数を使用していると仮定すると、Boost では、wait() ステートメントが自然な割り込みポイントであることを知っておくことが重要です。したがって、wait ステートメントを使用してコードの周りに try/catch ブロックを配置し、関数が catch ブロックで正常に終了できるようにします。

ここで、スレッド ポインターを含むコンテナーがあると仮定して、スレッド ポインターを反復処理し、各スレッドで interrupt() を呼び出し、続いて join() を呼び出します。

これで、すべてのスレッドが正常に終了し、Boost 関連のメモリ クリーンアップが正常に機能するはずです。

于 2012-08-20T22:31:23.933 に答える
0

非常に遅いですが、Windows(およびそのようなものを残すもののためのVMSやRSXのような前駆体)では、終了時に通知する完了ルーチンを備えたReadFileExのようなものを使用し、読み取りを早期にキャンセルする必要がある場合はCancelIOを使用します。

Linux / BSDには、まったく異なる基盤となるAPIがあり、柔軟性はありません。pthread_killを使用して信号を送信すると、読み取り/オープン操作が停止します。

プラットフォームごとに、この領域に異なるコードを実装する価値があります、IMHO。

于 2013-02-15T22:58:40.230 に答える
0

Windowsでは、QueueUserAPCを使用して、例外をスローするprocをキューに入れます。そのアプローチは私にとってはうまくいきます。

ただし、win32ではブーストミューテックスなどが「アラート可能」ではないため、QueueUserAPCがそれらを中断できないことがわかりました

于 2008-11-07T18:27:09.363 に答える
0

スレッドは、あなたがやりたいことを簡単な方法で行うのに役立っていないようです。Boost.Asio が気に入らない場合は、使用を検討してくださいselect()

アイデアは、2 つのファイル記述子を取得select()し、それらのどれが入力を利用できるかを示すために使用することです。cin通常、ファイル記述子は次のとおりSTDIN_FILENOです。他のものを取得する方法は、詳細に依存します(ファイルの場合はopen()、を使用する代わりにそれだけですifstream)。

ループを呼び出しselect()て、読み取る入力を見つけます。停止したい場合は、ループから抜け出します。

于 2009-08-08T13:32:09.427 に答える
0

スレッドを強制終了するのではなく、いつでも代わりにスレッドに参加できます。失敗した場合は、代わりに他のスレッドに参加します。(2 つのスレッドの少なくとも 1 つにいつでも参加できると仮定します)。

boost:thread では、 timed_join関数を探しています。

ただし、正しい答えを見たい場合は、時間指定された待機で非ブロッキング io を使用することになります。非同期 io のノンブロッキングを使用して、同期 io のフロー構造を取得できます。

あなたは istream からの読み取りについて話しますが、istream は単なるインターフェースです。標準入力の場合、標準入力ファイル記述子を fclose して読み取りを中断できます。もう1つは、どこから読んでいるかによって異なります...

于 2008-11-07T17:14:46.140 に答える