async_receive 中的 asio 底层行为

asio underlying behavior in async_receive

我已经在几个项目中使用 asio 库,并且总是设法让它工作,但我觉得其中有些东西我 entirely/clearly 到目前为止还没有理解。 我想知道 async_receive 是如何工作的。

我用谷歌搜索了一下,查看了实现,但不是很了解。这是我经常使用异步通信的方式:

socket.async_receive(receive_buffer, receiveHandler);

其中 receiveHandler 是数据到达套接字时将调用的函数。 我知道 async_receive 会立即调用 return。所以这是我的问题:

  1. 是否async_receive每次调用都会创建一个新线程? 如果没有,是否意味着有一个线程负责等待数据,当数据到达时,它会调用处理函数?此线程何时创建?
  2. 如果我使用像这样的 lambda 函数将此调用转换为递归调用:
void cyclicReceive() {
  // Imagine the whole thing is in a class, so "this" means something here and
  // "receiveHandler" is still a valid function that gets called.
  socket.async_receive(receive_buffer,
    [this](const asio::error_code& error_code, const std::size_t num_bytes) 
    {
       receiveHandler(error_code, num_bytes);
       cyclicReceive();
    });
}

有没有堆栈溢出的危险?为什么不呢?

我试图通过删除不必要的细节来展示一个最小的示例,因此确切的语法可能有点错误。

  1. Asio 不会隐式创建任何新线程。通常,它基于命令队列。当您调用 io.run() 时,框架会从队列中获取命令并执行它们,直到队列为空。 ASIO 中的所有 async_ 操作都会将新命令推送到内部队列。

  2. 因此不存在堆栈溢出的风险。最糟糕但不太可能的情况是 out_of_memory 异常,当命令队列中的命令没有 space 时(这不太可能)。