如何同时运行两个boost::asio::io_context实例以解决树莓派双连接运行异常问题?
解决Boost.Asio多个io_context同时运行的问题
这个问题我之前也碰到过,Boost.Asio的io_context.run()本身是阻塞式的——它会一直处理队列里的异步任务,直到没有待执行的任务才会返回。所以你先调用io.run(),程序就会卡在这一行,永远到不了io_context.run()那一步。给你两个实用的解决方案,按需选择:
方案1:用线程分别运行每个io_context
给每个io_context单独开一个线程,让它们的run()在不同线程里并行执行,这样就不会互相阻塞了。修改你的main函数如下:
boost::asio::io_context io_context; boost::asio::io_context io; int main() { // 创建服务器对象以接受客户端的连接请求 tcp_server server(io_context); open_port_arduino(); start = std::chrono::high_resolution_clock::now(); // 初始化时间 // 每隔2秒向Arduino写入数据 tim.expires_after(boost::asio::chrono::seconds {2}); tim.async_wait(timer_handler); // 从Arduino读取数据 start_read_arduino(); // 启动一个线程专门运行Arduino相关的io_context std::thread arduino_io_thread([&]() { io.run(); }); // 主线程运行TCP服务器的io_context io_context.run(); // 等待Arduino线程结束,避免程序提前退出 arduino_io_thread.join(); }
需要注意:如果其中一个io_context的所有任务都完成了(比如TCP服务器被关闭),对应的run()会返回,这时候你可以根据需求调用另一个io_context的stop()方法,让程序正常退出。
方案2:合并到同一个io_context(更推荐)
Boost.Asio官方其实更推荐尽量使用单个io_context来管理所有异步操作,除非你有明确的隔离需求(比如不同任务需要不同的线程优先级)。把TCP服务器、Arduino串口操作、定时器都绑定到同一个io_context,这样只需要调用一次run()就可以了,代码更简洁,还能避免线程管理的麻烦。
修改后的代码大概是这样:
// 只保留一个io_context boost::asio::io_context io; int main() { // TCP服务器也使用这个io_context tcp_server server(io); // 注意:open_port_arduino()、start_read_arduino()里的异步操作, // 也要改成使用这个io对象(比如串口对象的构造要传入io) open_port_arduino(); start = std::chrono::high_resolution_clock::now(); // 定时器同样绑定到这个io_context tim.expires_after(boost::asio::chrono::seconds {2}); tim.async_wait(timer_handler); start_read_arduino(); // 只需要运行一次,就能处理所有异步任务 io.run(); }
这个方案是最省心的,因为所有异步任务都在同一个事件循环里处理,不需要额外管理线程,也减少了线程同步的潜在问题。
额外提示:用work_guard保持io_context存活
如果你的某个io_context可能出现“暂时没有任务”的情况(比如Arduino暂时没有数据可读,也没有定时器任务),run()会自动返回,导致对应的线程退出。这时候可以用work_guard来让io_context一直保持“忙碌”状态,直到你主动停止它:
boost::asio::io_context io; // 创建work guard,让io_context不会因为没有任务而退出 auto work_guard = boost::asio::make_work_guard(io); std::thread arduino_thread([&]() { io.run(); }); // 当你需要停止的时候,重置work guard或者调用stop() // work_guard.reset(); // io.stop();
内容的提问来源于stack exchange,提问作者Bia
相关产品推荐
相关产品推荐

