简体   繁体   中英

boost::asio internal queue capacity

I was attempting to understand Boost Asio implementation and limitations. As I understand from here - https://www.boost.org/doc/libs/1_75_0/doc/html/boost_asio/overview/core/basics.html

When you do an async_receive_from call on a socket, the following things happen

  1. The socket forwards the request to the I/O execution context.
  2. The I/O execution context signals to the operating system that it should start an asynchronous connect.
  3. The operating system indicates that the connect operation has completed by placing the result on a queue, ready to be picked up by the I/O execution context.
  4. When using an io_context as the I/O execution context, your program must make a call to io_context::run() (or to one of the similar io_context member functions) in order for the result to be retrieved. A call to io_context::run() blocks while there are unfinished asynchronous operations, so you would typically call it as soon as you have started your first asynchronous operation.

Assuming I have very high throughput of data coming in, what I'm trying to understand is

  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?
  2. In step 3 above, OS puts completed reads in a queue. 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?

The ASIO code is open-source, but I'm fairly new to C++ and am finding it a little difficult to understand the code. Appreciate any help on these questions. Thanks!

There's no buffering in ASIO whatsoever; ASIO is a thin wrapper around native OS select / epoll / kqueue / IOCP (depending on OS) as well as non-blocking send / recv calls.

Your question can thus be re-phased as " what happens when I don't call recv fast enough? ". As it turns out, that question has already been asked before, see What happens if one doesn't call POSIX's recv “fast enough”? .

Anyway, to answer the specific questions:

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?

The OS can't get overwhelmed with async receive calls because you can have at most 1 active async receive and send per socket, and the number of sockets is limited.

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?

The queueing characteristics of a TCP stream are determined by the TCP receive buffer and TCP receive window. These are configurable in most modern OSes, and can even by dynamic. The receive buffer is bounded, and if you don't receive fast enough, TCP has built-in mechanisms to signal the sending side to slow down/retransmit (aka TCP Flow Control).

Similarly UDP has a receive buffer. When that one gets full, new incoming packets are dropped.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM