asio.run()的问题

在项目工程调试过程中,发现asio.run()出现了不预期的行为。详细探讨了这个问题,包括可能的原因及解决策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

昨天在调试项目工程的时候遇到了一个现象:

   因为,我在ocx和服务器之间做了一个tcp连接,为了检测连接是否断开,所以手动做了一个保活,即,每隔一段时间就给对方发送一个保活请求。当检测到连接断开后,ocx启动重新连接!问题来了,当重新连接后,程序不会退出重连,而是不断的连接。经过排查,问题的原因是:asio.run()的使用问题。

查询asio官网,在run函数的说明下面,有这么一句话:
The run() function must not be called from a thread that is currently calling one of run()run_one()poll() or poll_one() on the same io_service object.这句话的意思是,在一个io_service的线程中,如果已经调用过了run()run_one()poll() or poll_one(),那么久不能在调用run了。
但是,我们又必要要run函数在宝石io_service的正常运行,怎么办呢?于是,我看到了reset()函数。
This function must be called prior to any second or later set of invocations of the run(),
这也就是说,在我们第二次调用run函数之前,我们必须首先调用reset()函数,因为在我们第一次调用run结束之后,stopped()是返回true的,所以,如果我们第二次直接调用run,那么run是会直接退出的,reset会让stoped()返回false。
`boost/asio.hpp`是Boost.Asio库的一部分,专门用于异步I/O编程,包括事件驱动模型。Asio(Asynchronous I/O)允许你在C++中轻松地编写高效、非阻塞的网络和文件系统应用程序。 在这个库中,事件主要是通过`io_service`(IO服务对象)来管理的。`io_service`是一个事件循环的核心,它负责调度和处理各种任务和事件,如连接请求、接收数据、定时器等。当你启动一个异步操作(如发起一个网络连接或读取一个文件)时,实际上是在向`io_service`注册一个待处理的任务,并指定一个处理该事件完成后的回调函数。 举个例子,如果你想设置一个定时器并在指定时间后执行某个操作,可以这样做: ```cpp #include <boost/asio.hpp> // 创建io_service实例 boost::asio::io_service io; // 定义一个异步等待的时间量 const auto timeout = std::chrono::seconds(5); // 创建一个计时器 boost::asio::deadline_timer timer(io, timeout); // 当计时器到期时执行的回调函数 auto lambda = [io](const boost::system::error_code& ec) { if (!ec) // 如果没有错误,执行你的操作 do_something(); else // 处理错误 handle_error(ec); }; // 注册定时器到io_service,并开始异步等待 timer.async_wait(lambda); io.run(); // 这里会让程序阻塞直到定时器到期或者用户中断 ``` 在上述代码中,`async_wait`将当前的回调函数`lambda`添加到`io_service`的事件队列中,当计时器到达设定的时间时,`io_service`会唤醒并执行这个回调。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值