我注意到 boost.asio 有很多涉及套接字、串行端口和各种非文件示例的示例。谷歌并没有真正为我提供很多关于 asio 是否是执行异步文件 i/o 的好方法或有效方法的信息。
我有大量数据要异步写入磁盘。这可以通过 Windows(我的平台)中的本机重叠 io 来完成,但我更希望有一个独立于平台的解决方案。
我很好奇如果
- boost.asio 有任何类型的文件支持
- boost.asio 文件支持对于日常文件 i/o 来说已经足够成熟了
- 是否会添加文件支持?对此有何展望?
我注意到 boost.asio 有很多涉及套接字、串行端口和各种非文件示例的示例。谷歌并没有真正为我提供很多关于 asio 是否是执行异步文件 i/o 的好方法或有效方法的信息。
我有大量数据要异步写入磁盘。这可以通过 Windows(我的平台)中的本机重叠 io 来完成,但我更希望有一个独立于平台的解决方案。
我很好奇如果
从(我认为)Boost 1.36(包含 Asio 1.2.0)开始,您可以使用 [boost::asio::]windows::stream_handle 或 windows::random_access_handle 来包装 HANDLE 并对其执行异步读写方法在内部使用 OVERLAPPED 结构。
用户 Lazin 还提到 boost::asio::windows::random_access_handle 可用于异步操作(例如命名管道,也包括文件)。
由于 Boost.Asio 本身现在被广泛使用,并且实现在内部使用重叠 IO,我会说是的。
由于在Asio网站上没有找到路线图,我想说 Boost.Asio 不会为此功能添加新的内容。尽管贡献者总是有机会向 Boost.Asio 添加代码和类。也许您甚至可以自己贡献缺失的部分!:-)
Linux 上的 boost::asio 文件 i/o
在 Linux 上,asio 使用该epoll
机制来检测套接字/文件描述符是否准备好进行读/写。如果您尝试在 Linux 上的常规文件上使用 vanilla asio,您将收到“不允许操作”异常,因为epoll 不支持 Linux 上的常规文件。
解决方法是配置 asio 以select
在 Linux 上使用该机制。您可以通过定义BOOST_ASIO_DISABLE_EPOLL
. 如果您使用大量打开的套接字,这里的权衡往往比 epoll 慢。定期使用打开文件open()
,然后将文件描述符传递给boost::asio::posix::stream_descriptor
.
Windows 上的 boost::asio 文件 i/o
在 Windows 上,您可以使用从文件操作创建的boost::asio::windows::object_handle
包装。Handle
见例子。
boost::asio::windows::random_access_handle 是最简单的方法,如果你需要一些高级的东西,例如异步 LockFileEx 或其他东西,你可以扩展 asio,添加你自己的异步事件。例子
ASIO 在支持良好的 Windows 上支持重叠 I/O。在 Unix 上,这个想法停滞不前,原因是:
一个常见的例外是将文件直接提供给套接字。这是一种常见的特殊情况,Linux 有一个内核函数可以为您处理这个问题。再次否定使用异步文件 I/O 的原因。
简而言之:ASIO 似乎反映了底层 OS 设计理念,大多数 Unix 开发人员忽略了重叠 I/O,因此该平台不支持它。
io_uring 改变了一切。
asio 现在支持异步文件读/写。
请参阅发行说明:
asio 1.21.0 发行说明
Linux 有一个 asio 库,在这项工作中使用起来并不比 Windows API 难(我已经使用过它)。两组操作系统都实现了相同的概念架构。它们在与编写一个好的库相关的细节上有所不同,但并不是说你不能为两个操作系统平台提供一个通用接口(我已经使用过一个)。
基本上,所有类型的异步文件 I/O 都遵循“Fry Cook”架构。这就是我在读取操作上下文中的意思:我(处理线程)走到快餐柜台(OS)并要求一个芝士汉堡(一些数据)。它给了我一份订单票(一些数据结构)的副本,并在后面向厨师(内核和文件系统)发出一张票来烹饪我的汉堡。然后我坐下来或看手机(做其他工作)。后来,有人宣布我的汉堡准备好了(给处理线程的信号),我收集了我的食物(读取缓冲区)。