对于嵌入式系统接口,我实现了一个具有多达8种读取模式的类(下面的代码只显示了两种--FREERUN和BLOCKRUN),用于读取串行端口。此阅读器的简化ReaderTest()函数如下所示:
void CSerialBoost::ReaderTest()
{
while (RUNflag)
switch (RUNstate) {
case FREERUN:
port.async_read_some(asio::buffer(TextIn, SZTXT),
boost::bind(&CSerialBoost::OnReadFree, this, asio::placeholders::error, asio::placeholders::bytes_transferred));
server.reset();
server.run(error); // it calls OnReadBlock() here
break;
case BLOCKRUN:
port.async_read_some(asio::buffer(TextIn, SZTXT),
boost::bind(&CSerialBoost::OnReadBlock, this, asio::placeholders::error, asio::placeholders::bytes_transferred));
server.reset();
server.run(error); // it calls OnReadFree() here
break;
default: break;
}
port.cancel(error); // cancel all IO operations
}
CSerialBoost类具有以下成员:
asio::io_service server;
asio::serial_port port;
asio::error_code error;
volatile int RUNstate; // reader mode
volatile int RUNflag; // start/stop flag
当我从一种模式切换到另一种模式时,会出现意外行为。 假设没有传入数据并且代码在FREERUN中运行,为了从另一个线程切换到BLOCKRUN,我做了:
RUNstate = BLOCKRUN;
server.stop(); // unblock the event loop
操作切换到BLOCKRUN,就像它应该的那样,当它到达BLOCKRUN情况下的server.run(错误)行时,它调用CSerialBoost :: OnReadFree()函数并返回错误operation_aborted。当它切换回FREERUN时会发生同样的情况 - 它在FREERUN情况下到达server.run(错误)时调用CSerialBoost :: OnReadBlock()。
这是非常误导的,因为它总是调用其他模式的功能。当我停止/取消IO服务时,我希望每个案例都可以调用它自己的函数(或者什么都没有)。 我期待太多,还是这是正常的操作?难道我做错了什么? 请提示我如何处理这个问题。 (我正在使用boost:asio 1-5-3在Win XP和Win 7下,Visual Studio 2010,我是新手来提升)
谢谢你,MA。
答案 0 :(得分:0)
这是预期的行为。
io_service::stop()
和io_service::reset()
仅控制io_service
事件循环的状态;既不会影响为延迟调用(准备运行)或用户定义的处理程序对象安排的处理程序的生命周期。
当调用server.run()
时,async_read_some
操作已排队到io_service
。当事件循环通过server.stop()
显式停止时,如果尚未调用操作的完成处理程序,则操作或完成处理程序仍在io_service
中排队。然后执行继续执行while
循环,其中port.cancel()
强制取消port
上的未完成操作,将其完成处理程序设置为准备运行,错误代码为{{1 }}。因此,下次调用boost::asio::error::operation_aborted
时,将执行已取消操作的准备运行处理程序。
考虑:
server.run()
完成。这通常需要设置状态,取消未完成的操作,并阻止完成处理程序将其他工作发布到io_service
。 Boost.Asio提供了一个正式的timeout示例,并且还显示了运行到io_service
完成的超时方法here。io_service
,stop()
和重新reset()
run()
。io_service
对象的生命周期,因为io_service
的{{3}}将导致所有未处理的处理程序被销毁一种方法可以在destructor回答中找到。< / LI>