为什么 boost::asio::ip::tcp::basic_stream_socket::available 的运行



该方法boost::asio::ip::tcp::basic_stream_socket::available大约需要3us才能完成。这个时间量并不是特别慢,但仍然比我预期的只返回状态的方法调用要慢。需要这么长时间的原因是什么?它使用锁吗?如果是这样,并行的多个调用是否会遇到相互锁定争用的情况?

我会说这并不重要。为了直接回答这个问题,以下是对反应式套接字实现(例如Linux(所做的工作,预处理和重新格式化:

size_t available(socket_type s, boost::system::error_code& ec) {
if (s == invalid_socket) {
ec = boost::asio::error::bad_descriptor;
return 0;
}
ioctl_arg_type value = 0;
int result = error_wrapper(::ioctl(s, FIONREAD, &value), ec);
if (result == 0)
ec = boost::system::error_code();
return ec ? static_cast<size_t>(0) : static_cast<size_t>(value);
}

如您所见,它应该全部内联到直接FIONREADioctl,除非出现错误条件。这是非常精简的,如果你直接这样做,如果你想检查,不会花费更少的时间:

static inline size_t my_available(boost::asio::ip::tcp::socket& socket, boost::system::error_code& ec) {
auto s = socket.native_handle();
if (s == -1) {
ec = boost::asio::error::bad_descriptor;
return 0;
}
int value = 0;
if (auto err = ::ioctl(s, FIONREAD, &value))
ec = boost::system::error_code(err, boost::asio::error::get_system_category());
else
ec = boost::system::error_code();
return ec? value : 0;
}

反应堆式操作

如果您想等到数据可用并在第一时间采取行动,那么您可以在套接字上async_wait:https://www.boost.org/doc/libs/1_73_0/doc/html/boost_asio/reference/basic_stream_socket/async_wait.html

可以指定等待读/写可用性,或者当存在挂起的错误条件时

文档:https://www.boost.org/doc/libs/1_73_0/doc/html/boost_asio/overview/core/reactor.html

最新更新