是否应立即完成"stream.async_read_some(null_buffers,handler)&qu
Should `stream.async_read_some(null_buffers,handler)` complete immediately or not?
上下文:我正在与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。
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- 如何在 c++ 中'NULL'字符串
- c++使用foreach使数组为null
- 当使用通配符和null指针调用函数时,对输出的说明
- 当字段可以为null时,如何使用C++接口在Avro中写入数据
- 如何在映射中返回null
- 为什么返回 NULL 不会破坏函数?
- 构造函数中的 QQuickItem 父项 null
- 检查字符串是否"null" C++
- fopen 在 gdb 中返回 NULL
- what(): basic_string::_M_construct null not valid
- 在这个函数中是有缺陷的,因为取消引用 null 是无效的,所以我想更改代码
- 为什么在排序链表上的这种合并实现总是将两个列表都设置为 NULL,而只有一个应该设置一个列表?
- 为什么要从main()返回NULL?
- 为什么 nlohmann/json 序列化 "null" 而不是在 double 上"0"?
- 当目标指针不是基类的类型时,为什么允许dynamic_cast为多态类生成 null 指针?
- 是否有通用方法可以找到任何以 null 结尾的字符串的长度?
- 为什么TinyXML2的XMLDocument::FirstChild()函数在尝试解析这个有效的XML文件时返回NULL?
- 使用 curl_easy_cleanup(curl) 时收到未经处理的 NULL 异常
- ClassTemplateSpecializationDecl 的定义数据为 null