gpt4 book ai didi

boost - 如何使用 asio 执行非阻塞读取?

转载 作者:行者123 更新时间:2023-12-04 00:43:33 24 4
gpt4 key购买 nike

我正在尝试使用 boost::asio 从串行端口上的设备读取和写入。 boost::asio:read() 和 boost::asio::serial_port::read_some() 都会在没有可读取的内容时阻塞。相反,我想检测这种情况并向端口写入命令以启动设备。

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

如有必要,我可以异步完成所有操作,如果可以的话,我宁愿避免额外的复杂性。

最佳答案

实际上,您有几个选择。您可以使用串口内置的async_read_some函数,也可以使用独立函数boost::asio::async_read (或 async_read_some )。

您仍然会遇到被有效“阻止”的情况,因为除非(1)已读取数据或(2)发生错误,否则这些都不会调用回调。为了解决这个问题,您需要使用 deadline_timer对象设置超时。如果超时首先触发,则没有可用的数据。否则,您将读取数据。

增加的复杂性并不是那么糟糕。您最终会得到两个具有相似行为的回调。如果“读取”或“超时”回调因错误而触发,您就知道它是比赛失败者。如果其中一个触发没有错误,那么您知道它是比赛的获胜者(并且您应该取消另一个调用)。在您将阻止调用 read_some 的地方,您现在可以调用io_svc.run() .您的函数在调用 run 时仍会像以前一样阻塞。 ,但这次你控制持续时间。

这是一个例子:

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
}

这应该可以让您开始在这里和那里进行一些调整以满足您的特定需求。我希望这有帮助!

另一个注意事项:处理回调不需要额外的线程。一切都在对 run() 的调用中处理。 .不知道你是否已经意识到这一点......

关于boost - 如何使用 asio 执行非阻塞读取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/456042/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com