如何执行非阻塞使用ASIO看? [英] How do I perform a nonblocking read using asio?

查看:308
本文介绍了如何执行非阻塞使用ASIO看?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在串行端口上使用boost :: ASIO读取和写入的设备。双方的boost :: ASIO:阅读()和boost :: ASIO :: serial_port :: read_some()块的时候没有什么阅读。相反,我想检测到这种情况,写命令端口来启动该设备。

I am attempting to use boost::asio to read and write from a device on a serial port. Both boost::asio:read() and boost::asio::serial_port::read_some() block when there is nothing to read. Instead I would like to detect this condition and write a command to the port to kick-start the device.

我无论怎样才能检测到没有数据可用?

How can I either detect that no data is available?

如果有必要我可以异步做的一切,我只想而如果我能避免额外的复杂性。

If necessary I can do everything asynchronously, I would just rather avoid the extra complexity if I can.

推荐答案

您有几个选择,其实。您可以使用串行端口内置的 async_read_some 函数,也可以使用独立的功能的boost ::支持ASIO :: async_read (或 async_read_some )。

You have a couple of options, actually. You can either use the serial port's built-in async_read_some function, or you can use the stand-alone function boost::asio::async_read (or async_read_some).

您还是会碰到你在哪里有效的情况下封杀,因为没有这些将调用的回调,除非(1)数据已被读取或(2)发生错误。为了解决这个问题,你需要使用 deadline_timer 对象来设置超时。如果超时火灾第一,没有数据是可用的。否则,你会读出的数据。

You'll still run into the situation where you are effectively "blocked", since neither of these will call the callback unless (1) data has been read or (2) an error occurs. To get around this, you'll want to use a deadline_timer object to set a timeout. If the timeout fires first, no data was available. Otherwise, you will have read data.

增加的复杂性是不是真的那么糟糕。您将与两个回调有类似的行为结束。如果任一读或有错误的超时回调火灾,你知道这是比赛的失败者。如果任何一个火灾没有错误,那么你知道它的分站冠军(你应该取消其他电话)。在那里,你将有你的阻塞调用 read_some 的地方,你现在必须 io_svc.run()的调用。您的功能仍将块时,它调用之前运行,但这个时候你控制的持续时间。

The added complexity isn't really all that bad. You'll end up with two callbacks with similar behavior. If either the "read" or the "timeout" callback fires with an error, you know it's the race loser. If either one fires without an error, then you know it's the race winner (and you should cancel the other call). In the place where you would have had your blocking call to read_some, you will now have a call to io_svc.run(). Your function will still block as before when it calls run, but this time you control the duration.

下面是一个例子:

void foo()
{
  io_service     io_svc;
  serial_port    ser_port(io_svc, "your string here");
  deadline_timer timeout(io_svc);
  unsigned char  my_buffer[1];
  bool           data_available = false;

  ser_port.async_read_some(boost::asio::buffer(my_buffer),
      boost::bind(&read_callback, boost::ref(data_available), boost::ref(timeout),
                  boost::asio::placeholders::error,
                  boost::asio::placeholders::bytes_transferred));
  timeout.expires_from_now(boost::posix_time::milliseconds(<<your_timeout_here>>));
  timeout.async_wait(boost::bind(&wait_callback, boost::ref(ser_port),
                  boost::asio::placeholders::error));

  io_svc.run();  // will block until async callbacks are finished

  if (!data_available)
  {
    kick_start_the_device();
  }
}

void read_callback(bool& data_available, deadline_timer& timeout, const boost::system::error_code& error, std::size_t bytes_transferred)
{
  if (error || !bytes_transferred)
  {
    // No data was read!
    data_available = false;
    return;
  }

  timeout.cancel();  // will cause wait_callback to fire with an error
  data_available = true;
}

void wait_callback(serial_port& ser_port, const boost::system::error_code& error)
{
  if (error)
  {
    // Data was read and this timeout was canceled
    return;
  }

  ser_port.cancel();  // will cause read_callback to fire with an error
}

这应该让你开始在这里和那里只有一些调整,以满足您的特定需求。我希望这有助于!

That should get you started with only a few tweaks here and there to suit your specific needs. I hope this helps!

另注:没有额外的线程是必要的处理回调。一切都在调用运行中进行处理()。不知道你是否已经意识到了这一点......

Another note: No extra threads were necessary to handle callbacks. Everything is handled within the call to run(). Not sure if you were already aware of this...

这篇关于如何执行非阻塞使用ASIO看?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆