2

2 つのクライアントが通信できるようにするサーバーを使用してプログラムを設計しています。コマンドを実行するクライアントと、他のクライアントにコマンドを実行させる別のクライアントがあります。

これを機能させるために、2 つのスレッドがあります。1 つは制御対象クライアント用、もう 1 つはコントローラー クライアント用です。

制御されたクライアントは常に接続を維持し、タスクを含むベクトルを持ち、タスクが追加された場合にこれらのタスクを実行します。接続が閉じられると停止する無限 while ループがあります。

コントローラー クライアントはタスクをベクターに追加します。

2 つのスレッド間で共有されるベクトルがあるため、競合状態が発生する可能性がありますが、1 つのスレッドはオブジェクトを追加するだけで、もう 1 つのスレッドはオブジェクトをポップするだけなので、それは必要ですか? この問題でフローチャートを作ってみましたが、よくわからないかもしれません。フローチャートの作成方法がよくわかりません: ここに画像の説明を入力

std::vector <CustomClass>これを実現するために C++ から使用しています。

前もってありがとう、
ief2

編集: 追加の質問:vector.size()呼び出しにはミューテックスが必要ですか?

4

7 に答える 7

7

はい、これにはミューテックスが必要です。

vector.pop_front()vector.push_back()同時に実行すると、あらゆる種類の混乱が発生します。非標準が名前の意味するとおりに機能すると仮定しますvector.pop_front()

補足:ベクトルではなくキューまたはリストを使用する

于 2011-05-04T14:52:27.423 に答える
3

ベクターへのアクセスを制御する必要があります。プッシュとポップを同時にしようとしないでください。

于 2011-05-04T14:51:32.593 に答える
1

はい、ミューテックスが必要です。マルチプロセッサマシンでは、両方のスレッドが同時にプッシュとポップを試みている可能性があります。処理するものがある場合を示す条件変数も良い考えかもしれません。

于 2011-05-04T14:53:37.143 に答える
1

制御されたクライアントがどのように実装されているのか疑問に思います。タスクキューをチェックし続けるループですか?その場合、効率がより重要であると思われる場合は、タスクキューを単一リンクリストとして実装し、スレッドセーフでロックフリーの実装を維持できます。必要なのはリスト内のダムノードだけで、頭はこのダムノードを指しています。空のリストは、ダムノードの次のフィールドがnullとして表されます。ポップすると、現在のダムノードから新しいダムノードになる次のノードに頭を移動するだけです。プッシュすると、リストが空ではない(少なくともダムノードが含まれている)ため、タスクを追加するだけです。これは、2スレッドのシナリオでのみ機能します。

于 2011-05-04T20:43:57.920 に答える
0

STL コンテナーはスレッドセーフではありません。したがって、コンテナーをスレッドセーフにするためにロック機構 (つまりミューテックス) が必要です。

この SO の質問を読んで、スレッドセーフのために STL キューをラップする例を確認してください。

于 2011-05-04T14:56:09.183 に答える
0

通常、フローチャートは適切ではありません。

同期が必要です。std::vector複数のスレッドで を挿入または消去することは安全ではありません。

1 つのスレッドがプッシュし、同時に別のスレッドがポップした場合、プッシュによってベクトルの内部配列が再割り当てされるとどうなりますか? ポッピング スレッドは、使用されなくなった可能性のあるメモリにアクセスしています。

1 つのスレッドが読み取り中で、もう 1 つのスレッドがプッシュしている場合にも、同様の状況が発生する可能性があります。プッシュによってベクターが再割り当てされる場合、読み取りは、有効でなくなった可能性が最も高いメモリにアクセスしています。

于 2011-05-04T14:57:06.947 に答える
0

いいえ、ミューテックスは必要ありませんが、何らかの同期が必要です。無限ループは使用せず、代わりにイベントを使用することをお勧めします。共有コレクションへの書き込みが完了した場合はプロデューサーにシグナルを送信し、コマンドの読み取りが完了した場合はコンシューマーにシグナルを送信します (プロデューサーが書き込みを防止している間はコマンドの実行を開始しないでください)。

これにより、空のベクター内のコマンドをチェックする無駄な CPU サイクルが停止します。

于 2011-05-04T15:03:17.780 に答える