4

boost:asioのドキュメント(非同期クライアントではサイレントに表示されます)を読み、ここを調べましたが、ここでツリーのフォレストを見つけることができないようです。

次のようなメインループを持つシミュレーションがあります。

for(;;)
{
  a = do_stuff1();
  do_stuff2(a);
}

簡単です。

私がやりたいのは、次のように変更することです。

for(;;)
{
  a = do_stuff1();
  check_for_new_received_udp_data(&b);
  modify_a_with_data_from_b(a,b);
  do_stuff2(a);
}

次の要件がある場合:

  1. 積極的に聞いていなかったからといって、データを失うことはありません。IEサーバーがパケットを送信したときにcheck_for_new_received_udp_data()ではなくdo_stuff2()を使用していたため、パケットを失いたくありません。
  2. メインのforループは60Hzで実行する必要があるため、check_for_new_received_udp_data()ブロックを約2ms以上持つことはできません。
  3. サーバーは他の場所で実行され、スケジュールは完全に不安定になります。データがない場合もあれば、同じパケットを繰り返し取得する場合もあります。

私は非同期UDPで遊んだことがありますが、それは無期限にブロックするio_service.run()を呼び出す必要があるので、それは本当に私を助けません。

ブロッキングソケットの読み取りをタイムアウトすることを考えましたが、それを行うには、チートしてブースト呼び出しから抜け出す必要があるようです。そのため、これは初心者ではありません。

答えは糸脱毛を伴うのでしょうか?いずれにせよ、誰かが私にいくぶん似ている例を親切に指摘してもらえますか?確かにこれは以前に行われたことがあります。

4

2 に答える 2

3

でのブロックを回避するには、io_service :: poll_one()io_service::run()を使用できます。

UDPパケットを失うことに関して、私はあなたが運が悪いと思います。UDPは配信を保証するものではなく、トラフィックが多い場合、ネットワークのどの部分でもUDPパケットをドロップすることを決定する可能性があります。確実に配信する必要がある場合は、何らかのフロー制御を実装するか、TCPを使用する必要があります。

于 2013-03-24T21:17:12.487 に答える
3

あなたの問題は、あなたがまだ同期的に考えていることだと思います。非同期的に考える必要があります。

  1. UDPソケットでの非同期読み取り-データが到着するとハンドラーを呼び出します。
  2. そのハンドラー内で、受信データの処理を行います。処理中、スレッドが1つしかない場合は、他に何もディスパッチしないことに注意してください。これは完全に問題ありません(UDPメッセージは引き続きネットワークスタックのキューに入れられます...)。
  3. この結果、他の非同期操作を開始する可能性があります。

スレッドを含む本質的に無関係またはオフラインの作業を並行して行う必要がある場合。io_service.run()を呼び出すスレッドを作成します。

非同期フレームワークで定期的な作業を行う必要がある場合は、タイマーを使用してください。

あなたの特定の例では、次のようなものを再配置できます(psuedo-code):

read_handler( ... )
{
   modify_a_with_data_from_b(a,b);
   do_stuff2(a);
   a = do_stuff1();
   udp->async_read( ..., read_handler );
}

periodic_handler(...)
{
  // do periodic stuff
  timer.async_wait( ..., periodic_handler );
}

main()
{
   ...
   a = do_stuff1();
   udp->async_read( ..., read_handler )
   timer.async_wait( ..., periodic_handler );

   io_service.run();
}

今、あなたの質問からは明らかではない他の要件があると確信していますが、それらに対する非同期の答えを理解する必要があります。これは単なるアイデアです。また、非同期フレームワークが本当に必要なのか、それとも同期ソケットAPIを使用するだけなのかを自問してください。

于 2013-03-24T21:42:14.410 に答える