2

我正在为参加AI 比赛的机器人实现测试服务器,机器人通过标准输入/输出与服务器通信。机器人轮到他们的时间只有这么长。在之前的 AI 竞赛中,我用Java编写了服务器,并通过使用 BlockingQueue 和线程对进程流进行阻塞读/写来处理这个问题。

对于希望使用 C++ 的本次比赛。我找到了 Boost.Process和 Boost.Asio 但据我所知,Asio 库没有办法超时等待读取的时间。它的设计是围绕使用回调函数来告诉您读取何时完成。而我想阻止但最大超时。我可以使用特定于平台的 API(例如 select)来执行此操作,但要寻找更多的跨平台解决方案。有什么建议么?

编辑:为了澄清我想要一个类 BotConnection 来处理与具有两种方法的机器人进程进行通信,例如: string readLine(long timeoutInMilliseconds) 和 void writeLine(string line, long timeoutInMilliseconds) 。因此,调用代码的编写就像使用阻塞调用一样,但可以超时(抛出异常或更改上面的方法签名,因此如果操作完成或超时,则返回成功标志)

4

2 回答 2

0

没有可移植的方式来读取和写入超时的标准输入和输出。

  • Boost.Asio 提供posix::stream_descriptor对 POSIX 文件描述符的同步和异步读写,例如标准输入和输出,如posix 聊天客户端示例所示。虽然 Boost.Asio 不支持取消同步操作,但大多数异步操作都可以以可移植的方式取消。与 Boost.Asio Timers 结合的异步操作允许超时:在实体上启动异步操作,设置计时器,如果计时器到期,则cancel()在实体上调用。有关更多详细信息,请参阅 Boost.Asio超时示例
  • 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 回答