boost::asio 内部队列容量

boost::asio internal queue capacity

我试图了解 Boost Asio 的实现和限制。据我从这里了解到 - https://www.boost.org/doc/libs/1_75_0/doc/html/boost_asio/overview/core/basics.html

当您在套接字上执行 async_receive_from 调用时,会发生以下情况

  1. 套接字将请求转发到I/O执行上下文。
  2. I/O 执行上下文向操作系统发出信号,表明它应该启动异步连接。
  3. 操作系统通过将结果放入队列来指示连接操作已完成,准备好由 I/O 执行上下文拾取。
  4. 当使用 io_context 作为 I/O 执行上下文时,您的程序必须调用 io_context::run()(或类似的 io_context 成员之一函数)以便检索结果。当有未完成的异步操作时,对 io_context::run() 的调用会阻塞,因此您通常会在开始第一个异步操作后立即调用它。

假设我有非常高的数据吞吐量,我想了解的是

  1. 在上面的第 2 步中,IO 执行上下文发出信号 OS 以执行异步接收操作时,是否有可能丢失数据? OS 会不会不知何故被大量的异步读取淹没?
  2. 在上面的第 3 步中,OS 将完成的读取放入队列中。这个队列的容量是多少?例如,如果出现网络流量突发并且所有线程 运行 io_context::run() 都被占用,因此读取数据在队列中不断累积,这个队列是否会溢出?这个队列是有界的还是无界的?

A​​SIO 代码是开源的,但我是 C++ 的新手,发现理解代码有点困难。感谢对这些问题的任何帮助。谢谢!

ASIO 中没有任何缓冲; ASIO 是原生 OS select/epoll/kqueue/IOCP(取决于 OS)以及非阻塞的薄包装器send/recv 调用。

您的问题因此可以重新定位为“当我没有足够快地调用 recv 时会发生什么?”。事实证明,之前已经有人问过这个问题,请参阅 What happens if one doesn't call POSIX's recv “fast enough”?

总之,回答具体问题:

1. Is there a possibility of data loss in step 2 above where IO execution context signals OS to perform the async receive operation? Can the OS get somehow overwhelmed with the volume of asynchronous reads?

OS 不会被异步接收调用淹没,因为每个套接字最多可以有 1 个活动的异步接收和发送,并且套接字的数量是有限的。

2. ... What is the capacity of this queue? Can this queue overflow if for example, there was a burst of network traffic and all the threads running io_context::run() are occupied, hence read data keeps accumulating in the queue? Is this queue bounded or unbounded?

TCP 流的排队特性由 TCP 接收缓冲区和 TCP 接收决定window。这些在大多数现代 OSes 中都是可配置的,甚至可以动态配置。接收缓冲区是有界的,如果你的接收速度不够快,TCP 有内置的机制来通知发送端慢 down/retransmit(a.k.a。TCP 流量控制)。

同样UDP有一个接收缓冲区。当它变满时,新传入的数据包将被丢弃。