断开连接后正确杀死 asio steady_timer
Properly killing an asio steady_timer after a disconnect
我使用独立的 asio 编写了一个异步 SSL 套接字实现,并且在服务器重置/关闭连接后努力让它重新连接。我是 asio 库的新手,所以请多多包涵。
由于 steady_timer
,调用 io_context::run
的线程即使在断开连接后仍保持阻塞状态。我的 close()
逻辑负责重置套接字资源,还负责尝试终止计时器。这就是我的代码现在的样子:
正在创建我的异步作业:
timer.async_wait(std::bind(&ssl_socket::heartbeat, this));
在我的close()
方法中:
timer.expires_at(std::chrono::steady_clock::now());
timer.cancel();
根据boost docs,cancel()
应该:
Cancel any asynchronous operations that are waiting on the timer.
也许我误解了这一点,但我想这也会取消绑定到 io_context
的异步作业,但事实并非如此。 io_context::run
永远不会释放并造成死锁。
这是我的计时器处理程序的样子:
void ssl_socket::heartbeat() {
spdlog::get("console")->trace("heartbeat called");
if (connected_) {
write(heartbeat_token);
spdlog::get("console")->trace("heartbeat sent");
}
timer.expires_at(std::chrono::steady_clock::now() + std::chrono::seconds(heartbeat_interval));
timer.async_wait(std::bind(&ssl_socket::heartbeat, this));
}
我想让处理程序不必验证它是否应该更新其计时器并让 close()
处理它(如果可能的话)。
您忽略了错误代码。
According to the boost docs, cancel() should:
Cancel any asynchronous operations that are waiting on the timer.
这有点误导。当您阅读 cancel
函数的完整说明时,您会看到:
This function forces the completion of any pending asynchronous wait
operations against the timer. The handler for each cancelled operation
will be invoked with the boost::asio::error::operation_aborted
error
code.
这意味着,您的处理程序将被取消函数调用,并且由于您的处理程序只是重新设置到期时间并再次等待,因此循环永远不会结束。您需要检查错误代码,如果已设置,则跳出循环。
if(error) return;
我使用独立的 asio 编写了一个异步 SSL 套接字实现,并且在服务器重置/关闭连接后努力让它重新连接。我是 asio 库的新手,所以请多多包涵。
由于 steady_timer
,调用 io_context::run
的线程即使在断开连接后仍保持阻塞状态。我的 close()
逻辑负责重置套接字资源,还负责尝试终止计时器。这就是我的代码现在的样子:
正在创建我的异步作业:
timer.async_wait(std::bind(&ssl_socket::heartbeat, this));
在我的close()
方法中:
timer.expires_at(std::chrono::steady_clock::now());
timer.cancel();
根据boost docs,cancel()
应该:
Cancel any asynchronous operations that are waiting on the timer.
也许我误解了这一点,但我想这也会取消绑定到 io_context
的异步作业,但事实并非如此。 io_context::run
永远不会释放并造成死锁。
这是我的计时器处理程序的样子:
void ssl_socket::heartbeat() {
spdlog::get("console")->trace("heartbeat called");
if (connected_) {
write(heartbeat_token);
spdlog::get("console")->trace("heartbeat sent");
}
timer.expires_at(std::chrono::steady_clock::now() + std::chrono::seconds(heartbeat_interval));
timer.async_wait(std::bind(&ssl_socket::heartbeat, this));
}
我想让处理程序不必验证它是否应该更新其计时器并让 close()
处理它(如果可能的话)。
您忽略了错误代码。
According to the boost docs, cancel() should:
Cancel any asynchronous operations that are waiting on the timer.
这有点误导。当您阅读 cancel
函数的完整说明时,您会看到:
This function forces the completion of any pending asynchronous wait operations against the timer. The handler for each cancelled operation will be invoked with the
boost::asio::error::operation_aborted
error code.
这意味着,您的处理程序将被取消函数调用,并且由于您的处理程序只是重新设置到期时间并再次等待,因此循环永远不会结束。您需要检查错误代码,如果已设置,则跳出循环。
if(error) return;