100分求救~问一个boost asio用异步定时器处理串口的问题~~~~~~~~

时间:2022-09-08 23:13:33
菜鸟一只,学着用asio库做串口编程。
串口是要和硬件通信,协议没有分隔符,必须异步等待用定时器设置超时。

代码类似:
io_service iosev;
deadline_timer timer(iosev);
serial_port sp(iosev);
char buf[100]={0};

void handle_read(boost::system::error_code ec,
     std::size_t bytes_transferred)
{
     cout<<"buf:"+string(buf,bytes_transferred);
     //异步读回调时开始新的异步读
     async_read(sp, buffer(buf,100), handle_read);
     timer.expires_from_now(boost::posix_time::seconds(5));
     timer.async_wait(boost::bind(&serial_port::cancel, boost::ref(sp)));
}

int main()
{
     //打开并设置串口
      sp.open("COM1");
     sp.set_option(serial_port::baud_rate(19200));
     sp.set_option(serial_port::flow_control(serial_port::flow_control::none));
     sp.set_option(serial_port::parity(serial_port::parity::none));
     sp.set_option(serial_port::stop_bits(serial_port::stop_bits::one));
     sp.set_option(serial_port::character_size(8));    
     //异步读
     async_read(sp, buffer(buf,100), handle_read);
     timer.expires_from_now(boost::posix_time::seconds(5));
     timer.async_wait(boost::bind(&serial_port::cancel, boost::ref(sp)));

     //启动io_service
     iosev.run();
     cout<<"exit";
     return 0;
}

以上代码正常工作。现在问题是,假如定时器等待时间内收到了超过100字符,没到时间就进入回调,不知为什么,后面的异步读就不再等到超时才回调了,会看见高速的"buf:"刷屏。
经我测试(用expires_at输出字符串,用new每次新建定时器),定时器本身没有失效,问题是出在io_service上。
求各位高手支个招。

5 个解决方案

#1


修正抄写时的一点小问题。
标题加长~~~~~~~~~~

#2


帮顶... 顺便拿分

#3


没有高手教我吗?
我找到了一种方法,就是循环不通过回调函数,在main里做循环,一次循环结束调用io_service::reset。
这样不会有问题。
但是这样等于频繁开关它的事件循环,我怀疑不如官方例子的利用回调函数好。

#4


自己解决了。
结论是遇到那种情况reset run即可。
经测试,官方例子的做法不好,可能是一种无限递归,调用函数似乎会等下一个异步的回调函数返回才返回。内存明显有泄露。

#5


看来这里用boost的不多……

#1


修正抄写时的一点小问题。
标题加长~~~~~~~~~~

#2


帮顶... 顺便拿分

#3


没有高手教我吗?
我找到了一种方法,就是循环不通过回调函数,在main里做循环,一次循环结束调用io_service::reset。
这样不会有问题。
但是这样等于频繁开关它的事件循环,我怀疑不如官方例子的利用回调函数好。

#4


自己解决了。
结论是遇到那种情况reset run即可。
经测试,官方例子的做法不好,可能是一种无限递归,调用函数似乎会等下一个异步的回调函数返回才返回。内存明显有泄露。

#5


看来这里用boost的不多……