如何解决使用协程时 boost::asio 超时的最佳实践
下面的连接尝试(在我的网络配置上)造成了 2 分钟的延迟,因为目标不存在并且地址与我的机器位于不同的子网上。所以我添加了超时逻辑以将尝试限制为 5 秒:
#define BOOST_ASIO_HAS_CO_AWAIT
#define BOOST_ASIO_HAS_STD_COROUTINE
#include <iostream>
#include <chrono>
#include <thread>
#include <boost/asio/awaitable.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/address_v4.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/redirect_error.hpp>
namespace this_coro = boost::asio::this_coro;
using namespace std::chrono_literals;
boost::asio::awaitable<void> fail_to_connect()
{
auto executor = co_await this_coro::executor;
auto socket = boost::asio::ip::tcp::socket{executor};
auto ep = boost::asio::ip::tcp::endpoint{
boost::asio::ip::make_address_v4("192.168.1.52"),80};
auto timer = boost::asio::steady_timer{executor};
timer.expires_after(5s);
boost::asio::co_spawn(
executor,[&]() -> boost::asio::awaitable<void> {
auto ec = boost::system::error_code{};
co_await timer.async_wait(boost::asio::redirect_error(boost::asio::use_awaitable,ec));
std::cout << "Thread ID: " << std::this_thread::get_id()
<< " Timer: " << ec.message() << std::endl;
if (!ec) {
socket.close();
}
},boost::asio::detached
);
std::cout << "Thread ID: " << std::this_thread::get_id()
<< " Starting connection" << std::endl;
co_await boost::asio::async_connect(socket,std::array{std::move(ep)},boost::asio::use_awaitable);
timer.cancel();
}
int main()
{
auto ctx = boost::asio::io_context{};
auto guard = boost::asio::make_work_guard(ctx.get_executor());
auto exception_handler = [&](auto e_ptr) {
if (e_ptr) {
std::rethrow_exception(e_ptr);
}
};
boost::asio::co_spawn(ctx,fail_to_connect,std::move(exception_handler));
ctx.run();
}
这按预期工作。从线程 ID 可以看出,在两个协程之间使用相同的执行上下文意味着我也不会同时访问套接字。
14:58:41: Starting /home/cmannett85/workspace/build-scratch-Desktop-Debug/scratch ...
Thread ID: 140171855615808 Starting connection
Thread ID: 140171855615808 Timer: Success
terminate called after throwing an instance of 'boost::system::system_error'
what(): Operation canceled
14:58:46: The program has unexpectedly finished.
然而,这感觉很笨重,尤其是与非协程回调风格相比。使用协程有没有更好的超时方法?我正在努力寻找示例。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。