2

AI コンペティションに参加するボット用のテスト サーバーを実装しています。ボットは、標準の入出力を介してサーバーと通信します。ボットのターンは非常に長いです。以前の AI コンテストで、私はJavaでサーバーを作成し、BlockingQueue とプロセス ストリームへの読み取り/書き込みをブロックするスレッドを使用してこれを処理しました。

このコンペティションでは、C++ の使用を検討しています。Boost.Processと Boost.Asioを見つけましたが、私が知る限り、Asio ライブラリには読み取りを待機する時間をタイムアウトにする方法がありません。コールバック関数を使用して、読み取りが完了したことを通知するように設計されています。ブロックしたいのですが、タイムアウトが最大です。selectのようなプラットフォーム固有のAPIでこれを行うことができますが、より多くのクロスプラットフォームソリューションを探しています。助言がありますか?

編集:明確にするために、2つのメソッドを持つボットプロセスとの通信を処理するクラス BotConnection が必要です: string readLine(long timeoutInMilliseconds) と void writeLine(string line, long timeoutInMilliseconds) 。したがって、呼び出しコードは、ブロッキング呼び出しを使用しているように記述されていますが、タイムアウトする可能性があります (例外をスローするか、上記のメソッド シグネチャを変更して、操作が完了またはタイムアウトした場合に成功フラグが返されるようにします)。

4

2 に答える 2

0

タイムアウトを使用して標準入力および標準出力を読み書きする移植可能な方法はありません。

  • Boost.Asio は、 posix チャット クライアントの例posix::stream_descriptorで示されているように、標準入出力などの POSIX ファイル記述子に対して同期的および非同期的に読み取りおよび書き込みを行う機能を提供します。Boost.Asio は同期操作のキャンセルをサポートしていませんが、ほとんどの非同期操作は移植可能な方法でキャンセルできます。Boost.Asio タイマーと組み合わせた非同期操作により、タイムアウトが可能になります。エンティティで非同期操作が開始され、タイマーが設定され、タイマーが期限切れになるとエンティティで呼び出されます。詳細については、Boost.Asioタイムアウトの例を参照してください。cancel()
  • Windows 標準ハンドルは、完了ポートを介した非同期 I/O をサポートしていません。したがって、Boost.Asio のwindows::stream_handleドキュメントには、名前付きパイプはサポートされていますが、匿名パイプとコンソール ストリームはサポートされていないと記載されています。標準入出力ハンドルの非同期 I/O サポートに関して、このような未回答の質問がいくつかあります。非同期サポートがないため、アプリケーションからプラットフォーム固有の動作を抽象化するために、追加のスレッドとバッファリングが必要になる場合があります。
于 2013-11-06T20:34:43.990 に答える
0

タイムアウトを追跡するタイマー オブジェクトを作成できます。典型的なアプローチは、非同期ハンドラーを使用して通常のタイマーを作成することです。起動するたびに、データを送信していない接続オブジェクトを探して接続オブジェクトを反復処理します。接続読み取りハンドラーで、データを受信したことを示すフラグをオブジェクトに付けます。大まかな擬似コードでは:

timer_handler:
  for cnx in connections:
    if cnx.recv_count > 0:
      cnx.recv_count = 0
      cnx.idle_count = 0
      continue

    cnx.idle_count += 1
    if cnx.idle_count > idle_limit:
      cnx.close()


cnx_read_handler:
  cnx.recv_count += 1

注:asioは使用していませんが、チェックしたところ、タイマーが提供されているようです。

于 2013-11-06T08:10:34.410 に答える