2

スレッド間通信について一般的な質問があります。

現在、私はたくさんのC ++スレッド(〜15)を使用しています。

それらはすべて、処理するデータを取得するために互いにBusyWait(Polling)を使用しています。ただし、CPU使用率を低く抑えることは困難であり、良好なパフォーマンスを提供し、コンテキストスイッチを多用しないようにします。

だから私は条件変数とシグナルを見ています。スレッドで.Wait()に入り、.Signal()を呼び出す別のスレッドを待つという一般的な概念を理解していると思います。

質問#1)私の問題は概念的なものかもしれませんが、シグナルを待機しているスレッドが待機中にSUSPENDEDになると、それ自体ではアクションを実行できなくなります。とにかくそれがいくつかのアクションを実行するためにそれ自体で目を覚ますようにすることはありますか?

質問#2)さらに、私のクラスは両方向にデータを渡すために使用されます。ただし、ミドルクラスが別のクラスからのシグナルを待機している場合、そのクラスにシグナルを送信することはできません。そのような:

 _________                       _________                       __________
| Class A |---newData Signal--->| Class B |---newData Signal--->| Class C  |
|         |                     |(WAITING)|<---newData Signal---|          |
 ---------                       ---------                       ----------

したがって、クラスBがCからの.Signal()に対して.Wait()をオンにしている場合、Aからの新しいシグナルを処理することはできません。

A && Cの両方が同じ「newData」信号Bを送信して、それをウェイクアップすることは可能ですか?信号をA&&Cと区別することは可能でしょうか。

私はACEフレームワークを使用してC++を使用してこれをコーディングしており、Boostに切り替える可能性があります。しかし、これは十分に一般的であり、どのOSにも答えを適用できると思います(うまくいけば)。

ありがとう

4

5 に答える 5

2

子スレッドの実行中に親スレッドを動作させたい場合は、タイムアウトを指定してシグナルを待つことができます。タイムアウトが切れるたびに、何らかの作業を行い、再び待機します。

于 2009-06-04T12:49:06.567 に答える
1

質問 #1) ほとんどの実装では、最大待機時間を制限できます。つまり、2 秒待ってから何かを実行して、もう一度待機します。

質問 #2) ほとんどの実装では、一度に複数のシグナルを待つことができます。あなたは言うことができます:信号AまたはBがトリガーされた場合、目を覚ます。

于 2009-06-04T12:54:31.160 に答える
0

これには条件変数を使用できますが、問題の説明では、代わりにメッセージ キューを使用することをお勧めします。その後、スレッド A とスレッド C はメッセージを B のキューに挿入でき、B はそれに応じてメッセージを処理します。(もちろん、2 つのスレッドを区別するには、A と C が異なるメッセージを送信するように調整する必要があります。)

ACE がメッセージ キューをどのようにサポートしているかはわかりませんが、(たとえば) Java 同時実行フレームワークでは、 を使用して独自の簡易メッセージ キューを構築できますConcurrentLinkedQueue。:-)

于 2009-06-04T13:01:02.517 に答える
0

あなたが求める答えは非常に複雑で、この wiki のスペースはそれらすべてに対処するには十分ではありません :(

必要なことは、スレッド化の仕組みを説明している優れた Web サイトを自分で見つけることです。あなたが求めていることのほとんどは、正しい設計で行うことができますが、最初に概念をよりよく理解する必要があります.

通信を機能させるには、信号を適切な場所に送信し、適切なイベントを待機する必要があります。

これを行う最も簡単な方法は、すべてのスレッドが共有する単一の条件変数を使用することです。この状態が通知されると、それらはすべて目を覚まし、やるべき仕事を探します。

これは効率的ではありませんが、単純であり、うまく機能し、ポーリングよりも効率的です。これが機能したら、いくつかの新しい条件変数を導入して、どのスレッドがどのスレッドを待機するかを分割することができます。これを行うと、多くの間違いを犯し、多くのデッドロックと飢餓を経験することになります。辛抱すれば、これがどのように機能するかを理解し始めるでしょう。

幸運を。

于 2009-06-04T12:54:33.747 に答える
0

クリティカル セクションのロック (Java 同期など) またはスレッド セーフ キューを行う何らかの方法があると仮定すると、実行キューを使用できます。

スレッドごとに、スリープの実装を変更/オーバーライドして、スレッドが待機するときに実行キューの最後に追加されるようにします。

一度に 1 つのスレッドのみを実行する必要があると仮定すると、現在実行中のスレッドがスリープ/待機状態になる前に最後に実行する必要があるのは、リストの先頭にあるスレッドを起動することです。

スレッドのより複雑な実行/スケジューリングが必要な場合、次のステップは、キューをたどるスケジューラ スレッドを作成し、キュー内のスレッドの順序を調整し、どのスレッドが実行に必要なすべてのリソースを持っているかを確認することです。 .

于 2009-06-04T13:31:03.923 に答える