50

我注意到 boost.asio 有很多涉及套接字、串行端口和各种非文件示例的示例。谷歌并没有真正为我提供很多关于 asio 是否是执行异步文件 i/o 的好方法或有效方法的信息。

我有大量数据要异步写入磁盘。这可以通过 Windows(我的平台)中的本机重叠 io 来完成,但我更希望有一个独立于平台的解决方案。

我很好奇如果

  1. boost.asio 有任何类型的文件支持
  2. boost.asio 文件支持对于日常文件 i/o 来说已经足够成熟了
  3. 是否会添加文件支持?对此有何展望?
4

6 回答 6

20

boost.asio 有任何类型的文件支持吗?

从(我认为)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 文件支持对于日常文件 i/o 是否足够成熟?

由于 Boost.Asio 本身现在被广泛使用,并且实现在内部使用重叠 IO,我会说是的。

是否会添加文件支持?对此有何展望?

由于在Asio网站上没有找到路线图,我想说 Boost.Asio 不会为此功能添加新的内容。尽管贡献者总是有机会向 Boost.Asio 添加代码和类。也许您甚至可以自己贡献缺失的部分!:-)

于 2008-12-18T17:31:11.967 回答
7

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例子

于 2016-02-09T16:27:31.673 回答
5

boost::asio::windows::random_access_handle 是最简单的方法,如果你需要一些高级的东西,例如异步 LockFileEx 或其他东西,你可以扩展 asio,添加你自己的异步事件。例子

于 2008-12-18T19:18:57.537 回答
4

ASIO 在支持良好的 Windows 上支持重叠 I/O。在 Unix 上,这个想法停滞不前,原因是:

  • 文件通常位于同一物理设备上,最好按顺序访问它们。
  • 文件请求通常会很快完成,因为它们在物理上就在附近。
  • 文件通常对于完成程序的基本操作至关重要(例如,必须在进一步初始化之前读取其配置文件)

一个常见的例外是将文件直接提供给套接字。这是一种常见的特殊情况,Linux 有一个内核函数可以为您处理这个问题。再次否定使用异步文件 I/O 的原因。

简而言之:ASIO 似乎反映了底层 OS 设计理念,大多数 Unix 开发人员忽略了重叠 I/O,因此该平台不支持它。

于 2012-02-20T14:48:22.573 回答
1

io_uring 改变了一切。
asio 现在支持异步文件读/写。
请参阅发行说明:
asio 1.21.0 发行说明

于 2021-11-10T03:48:51.113 回答
0

Linux 有一个 asio 库,在这项工作中使用起来并不比 Windows API 难(我已经使用过它)。两组操作系统都实现了相同的概念架构。它们在与编写一个好的库相关的细节上有所不同,但并不是说你不能为两个操作系统平台提供一个通用接口(我已经使用过一个)。

基本上,所有类型的异步文件 I/O 都遵循“Fry Cook”架构。这就是我在读取操作上下文中的意思:我(处理线程)走到快餐柜台(OS)并要求一个芝士汉堡(一些数据)。它给了我一份订单票(一些数据结构)的副本,并在后面向厨师(内核和文件系统)发出一张票来烹饪我的汉堡。然后我坐下来或看手机(做其他工作)。后来,有人宣布我的汉堡准备好了(给处理线程的信号),我收集了我的食物(读取缓冲区)。

于 2013-10-04T15:21:02.357 回答