繁体   English   中英

boost :: asio调用了错误的串口处理程序

[英]boost::asio calls the wrong handler for serial port

对于嵌入式系统接口,我正在实现一个类,该类最多具有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()函数,并带有error operation_aborted错误。 当它切换回FREERUN时,也会发生相同的情况-在FREERUN情况下,当它到达server.run(error)时,它将调用CSerialBoost :: OnReadBlock()。

这很容易引起误解,因为它总是为其他模式调用该函数。 当我停止/取消IO服务时,我希望每种情况都调用其自己的函数(或不执行任何操作)。 我是否期望过高,或者这是正常操作? 难道我做错了什么? 请提示我该如何处理。 (我在Win XP和Win 7,Visual Studio 2010下使用boost:asio 1-5-3,我是新手来增强)

谢谢你,MA。

这是预期的行为。

io_service::stop()io_service::reset()仅控制io_service的事件循环的状态。 既不会影响为延迟调用(准备运行)而安排的处理程序的寿命,也不会影响用户定义的处理程序对象的寿命。

server.run()被调用时, async_read_some操作已排队到io_service 当通过server.stop()显式停止事件循环时,如果尚未调用操作的完成处理程序,则该操作或完成处理程序将保留在io_service排队。 然后执行在while循环中继续,其中port.cancel()强制取消port上的未完成操作,将其完成处理程序设置为可以运行,错误代码为boost::asio::error::operation_aborted 因此,下次调用server.run() ,将执行已取消操作的准备运行处理程序。

考虑以下任一情况:

  • 运行io_service完成。 这通常需要设置状态,取消未完成的操作以及防止完成处理程序将其他工作发布到io_service Boost.Asio提供了一个官方的超时示例, 此处还显示一个超时方法,该方法运行io_service来完成。
  • 让异步调用链实现状态机。 这样可以避免需要对io_service进行stop()reset()和re- run()的操作。
  • 控制的寿命io_service对象,如析构函数io_service将导致所有优秀的处理程序被破坏中可以找到一种方法这个答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM