对于嵌入式系统接口,我正在实现一个具有多达 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(error) 行时,它调用 CSerialBoost::OnReadFree() 函数,错误为 operation_aborted。当它切换回 FREERUN 时也会发生同样的情况——它在 FREERUN 情况下到达 server.run(error) 时调用 CSerialBoost::OnReadBlock()。
这是非常具有误导性的,因为它总是调用其他模式的函数。当我停止/取消 IO 服务时,我希望每个案例都调用自己的函数(或什么都不调用)。是我期望太高,还是这是正常操作?难道我做错了什么?请提示我如何处理这个问题。(我在 Win XP 和 Win 7、Visual Studio 2010 下使用 boost:asio 1-5-3,而且我是 boost 新手)
谢谢你,妈妈。