C++ 如何在C+中执行跨平台异步文件I/O+;

C++ 如何在C+中执行跨平台异步文件I/O+;,c++,file,asynchronous,cross-platform,io,C++,File,Asynchronous,Cross Platform,Io,我正在编写一个应用程序,需要使用大型音频多样本,通常大小约为50MB。一个文件包含大约80个单独的短录音,我的应用程序可以随时播放这些录音。因此,所有音频数据都会加载到内存中,以便快速访问 然而,当加载其中一个文件时,可能需要几秒钟才能将其放入内存,因为我需要使用ifstream读取大量数据,这意味着我的程序GUI暂时冻结。我曾尝试过对文件进行内存映射,但每次我需要跳转到文件的不同区域时,这会导致巨大的CPU峰值和混乱的音频,这是不可接受的 因此,这让我认为执行异步文件读取将解决我的问题,即数据

我正在编写一个应用程序,需要使用大型音频多样本,通常大小约为50MB。一个文件包含大约80个单独的短录音,我的应用程序可以随时播放这些录音。因此,所有音频数据都会加载到内存中,以便快速访问

然而,当加载其中一个文件时,可能需要几秒钟才能将其放入内存,因为我需要使用ifstream读取大量数据,这意味着我的程序GUI暂时冻结。我曾尝试过对文件进行内存映射,但每次我需要跳转到文件的不同区域时,这会导致巨大的CPU峰值和混乱的音频,这是不可接受的

因此,这让我认为执行异步文件读取将解决我的问题,即数据在不同的进程中读取,并在完成时调用函数。Mac OS X和Windows以及C++中都需要兼容。
编辑:我不想使用Boost库,因为我想保留一个小的代码库。

Boost.Asio库对异步文件I/O操作的实现有限(仅适用于句柄的Windows包装器),因此它不适合您。另见问题


您可以使用标准流和Boost.Thread库(或特定于平台的线程支持)轻松实现自己的异步读取。

Boost有一个asio库,我以前从未使用过(它不在NASA批准的第三方库列表中)

我自己的方法是编写两次文件读取代码,一次用于Windows,一次用于POSIX aio API,然后选择一个合适的链接

对于Windows,使用重叠(必须在CreateFile调用中启用它,然后在读取时传递重叠结构)。您可以让它在完成时设置事件(ReadFile)或调用完成回调(ReadFileEx)。您可能需要更改主事件循环以使用MsgWaitForMultipleObjectsEx,以便除了接收WM_uu窗口消息外,还可以等待I/O事件或允许回调运行。MSDN有这些函数的文档

对于Linux,有fadvise和epoll,它们将使用readahead缓存,也有aio_read,它们将允许实际的异步读取请求。当请求完成时,您将收到一个信号,您应该使用该信号发布XWindows消息并唤醒事件处理循环


两者在细节上略有不同,但最终效果是相同的——您请求在后台完成的读取,然后在I/O完成时唤醒您的事件调度循环。

是的,我之前已经写了两次,一次用于Windows,一次用于POSIX,所以这不会是问题。在哪里可以读取POSIX和Windows的异步文件I/O以便编写它?我不想使用boost,因为我想保留我的小代码base.MSDN(适用于Windows)、手册页(适用于Linux)和谷歌(google)也很棒。我编辑了我的答案,概述了它是如何工作的,并为您提供了您想要研究的关键函数的名称。re:Boost.asio,它也是作为独立版本存在的,请注意,您也可以以较小的块读取数据,这不会花费太多时间,然后让事件循环在其间运行。这是多线程,而不是异步I/O,它让程序员负责跨线程同步访问,取消请求是一件非常痛苦的事情。使用真正的异步读取。