3

というわけで、こんな状況です。wait()受信メッセージをブロックして待機する関数を使用して、プロセス間通信を行う C++ ライブラリがあります。問題は、指定された時間内にメッセージが受信されない場合にステータス値を返す、時間指定の待機が必要なことです。

最も洗練された解決策は、おそらくライブラリを書き直して、その API に時限待機を追加することですが、この質問のために、それは実現可能ではないと仮定します。(実際には難しそうなので、他にどんな選択肢があるのか​​知りたいです。)

疑似コードでビジー待機ループを使用してこれを行う方法は次のとおりです。

while(message == false && current_time - start_time < timeout)
{
  if (Listener.new_message()) then message = true;
}

ただし、プロセッサ サイクルを消費するビジーな待機は望ましくありません。また、プロセッサの負荷を回避するためにループに呼び出しを追加したくありませんsleep()。これは、応答が遅くなることを意味します。適切な種類のブロックと割り込みでこれを行うものが必要です。より良い解決策にスレッド化が含まれる場合 (可能性が高いと思われます)、既に を使用しているboost::threadので、それを使用することをお勧めします。

これはかなり一般的なパターンであるため、明確な「ベストプラクティス」の正しい答えがあるような状況のように思われるため、この質問を投稿しています。それを行う正しい方法は何ですか?

追加する編集:ここでの私の懸念の大部分は、これがプログラム内のパフォーマンスが重要であり、競合状態やメモリリークを回避するために重要な場所にあるということです。したがって、「2 つのスレッドと 1 つのタイマーを使用する」というアドバイスは役に立ちますが、実際にそれを安全かつ正しい方法で実装する方法を見つけようとしているところが残っています。作ったことすら知りません。したがって、いくつかの実際のサンプルコードは本当にありがたいです!

また、マルチスレッド ソリューションについて懸念があります。 ? 最初のスレッドの時限待機が返されることはわかっており、応答が発生せず、処理が続行されることがわかりますが、その後、ブロックされた状態で永遠に座っているスレッドを「リーク」しましたか? それを回避する方法はありますか?(それを回避し、2 番目のスレッドのメモリのリークを回避する方法はありますか?) ブロッキング呼び出しが返されない場合にリークを回避するために必要なものに対する完全な解決策が必要です。

4

6 に答える 6

1

ブロッキング呼び出しを別のスレッドにカプセル化します。そのスレッドに、条件変数によって保護されている中間メッセージバッファーを用意します(前述のとおり)。メインスレッドを時間指定します-その条件変数で待機します。条件が満たされた場合、中間に保存されたメッセージを受信します。

したがって、基本的には、APIとアプリケーションの間に時限待機が可能な新しいレイヤーを配置します。アダプターパターン。

于 2010-11-20T12:35:55.453 に答える
1

sigaction(2)とを使用できますalarm(2)。どちらもPOSIXです。sigactionを使用してタイムアウトのコールバックアクションを設定し、次にアラームを使用してタイマーを設定してから、ブロッキング呼び出しを行います。選択したタイムアウト(秒単位。より細かい粒度が必要な場合は使用できますsetitimer(2))内にブロック呼び出しが完了しない場合、ブロッキング呼び出しは中断されます。

Cの信号はやや厄介であり、信号ハンドラーで実行できることにはかなり厄介な制限があることに注意してください。

このページは便利でかなり簡潔です: http ://www.gnu.org/s/libc/manual/html_node/Setting-an-Alarm.html

于 2010-11-20T17:21:09.257 に答える
1

必要なのは、ターゲットにしている OS に応じて、select(2)のようなものです。

于 2010-11-20T10:43:38.220 に答える
1

共有ミューテックスを介してスレッドにリソースの可用性を通知できる「モニター」が必要なようです(通常)。Boost.Thread では、condition_variableがその役割を果たします。

于 2010-11-20T11:33:10.367 に答える
1

時限ロックを見たいと思うかもしれません: ブロッキングメソッドは、待機を開始する前にロックを取得し、データが利用可能になるとすぐにロックを解放できます。その後、timed wait メソッドで (タイムアウトを使用して) ロックの取得を試みることができます。

于 2010-11-20T11:42:27.557 に答える