是否应立即完成"stream.async_read_some(null_buffers,handler)&qu

Should `stream.async_read_some(null_buffers,handler)` complete immediately or not?

本文关键字:buffers null handler qu some 是否 quot stream 应立即 async read      更新时间:2023-10-16

上下文:我正在与Boost ASIO集成的RDMA包装库之上实现一个简单的流适配器。

我遇到的问题是,如果内部接收缓冲区中没有更多挂起的数据,即使流返回了足够的数据来填充缓冲区时,客户端代码调用的boost::asio::async_read聚合器也会挂起。调试显示它正在使用大小为0的单个缓冲区调用流适配器的async_read_some方法。

我发现的文档似乎在操作是否应该立即完成的问题上存在冲突。一方面,AsyncReadStream概念规范说:

如果序列mb中所有缓冲区的总大小为0,则异步读取操作应立即完成,并将0作为参数传递给指定读取字节数的处理程序。

另一方面,boost::asio::null_buffers的概述说:

null_buffers操作在I/O对象"准备好"执行该操作之前不会返回。

(事实上,在其他地方,当rdma_cm和ibverbs完成通道FD指示可用事件时,我依靠它来注册要调用的处理程序。)但看看null_buffers的实现,它似乎只是一个不包含缓冲区的静态对象,因此似乎满足所有缓冲区的总大小为0的序列的条件。

因此,我对async_read_some方法应该如何处理尝试读取0字节的情况感到困惑。作为一个粗略的猜测,也许它应该是这样的:在像null_buffers这样的真正空的序列上,它应该只有在接收缓冲区中有可用数据时才完成,而如果它有一个缓冲区总长度等于0的非空序列,那么它应该立即完成,而不管接收缓冲区的状态如何?

注意 null_buffers自Boost 1.66.0:以来一直被弃用:"(已弃用:使用套接字/描述符wait()和async_wait()成员函数。)">

作为一个粗略的猜测,也许它应该是这样的:在像null_buffers这样真正空的序列上,它应该只有在接收缓冲区中有可用数据时才完成,而如果它有一个缓冲区总长度等于0的非空序列,那么它应该立即完成,而不管接收缓冲区的状态如何?

否。null_buffers不是"空缓冲区"或"零长度缓冲区"。它是"无缓冲区",向ASIO例程发出信号,表明没有缓冲区(因此在逻辑上不能认为大小为零)。

所有与缓冲区大小相关的完成注释都是不相关的,因为不存在缓冲区。相关文件是反应堆式操作

你说得对:传递null_buffers信号,表明你希望一个反应器式操作编织到asio事件子系统中(也就是说,你可以异步等待套接字准备好读/写,然后执行实际的IO,例如将底层套接字句柄传递给本机不支持异步IO的第三方API。