如何在C ++中执行跨平台异步文件I / O. [英] How to perform Cross-Platform Asynchronous File I/O in C++

查看:119
本文介绍了如何在C ++中执行跨平台异步文件I / O.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



然而,当加载其中一个文件时,可能需要很长时间才能放入内存,因为我需要使用ifstream读取大量数据,这意味着我的程序GUI暂时被冻结。我已经尝试了内存映射我的文件,但每次我需要跳转到文件的不同区域时,这会导致巨大的CPU峰值和乱七八糟的音频,这是不可接受的。



<因此,这让我认为执行异步文件读取将解决我的问题,即数据在不同的进程中读取并在完成时调用函数。这需要兼容Mac OS X和Windows以及C ++。



编辑:不想使用Boost库,因为我想保留一个小代码基础。

解决方案

boost有一个asio库,我以前没用过它(它不在NASA的批准的第三个列表中 - 派对图书馆)。



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



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



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



两者都有一点不同细节,但净效果是相同的 - 您请求读取在后台完成,然后您的事件调度循环在I / O完成时被唤醒。


I am writing an application needs to use large audio multi-samples, usually around 50 mb in size. One file contains approximately 80 individual short sound recordings, which can get played back by my application at any time. For this reason all the audio data gets loaded into memory for quick access.

However, when loading one of these files, it can take many seconds to put into memory because I need to read a large amount of data with ifstream, meaning my program GUI is temporarily frozen. I have tried memory mapping my file but this causes huge CPU spikes and a mess of audio every time I need to jump to a different area of the file, which is not acceptable.

So this has led me to think that performing an Asynchronous file read will solve my problem, that is the data gets read in a different process and calls a function on completion. This needs to be both compatible for Mac OS X and Windows and in C++.

EDIT: Don't want to use the Boost library because I want to keep a small code base.

解决方案

boost has an asio library, which I've not used before (it's not on NASA's list of approved third-party libraries).

My own approach has been to write the file reading code twice, once for Windows, once for the POSIX aio API, and then just pick the right one to link with.

For Windows, use OVERLAPPED (you have to enable it in the CreateFile call, then pass an OVERLAPPED structure when you read). You can either have it set an event on completion (ReadFile) or call a completion callback (ReadFileEx). You'll probably need to change your main event loop to use MsgWaitForMultipleObjectsEx so you can either wait for the I/O events or allow callbacks to run, in addition to receiving WM_ window messages. MSDN has documentation for these functions.

For Linux, there's either fadvise and epoll, which will use the readahead cache, or aio_read which will allow actual async read requests. You'll get a signal when the request completes, which you should use to post an XWindows message and wake up your event processing loop.

Both are a little different in the details, but the net effect is the same -- you request a read which completes in the background, then your event dispatch loop gets woken up when the I/O finishes.

这篇关于如何在C ++中执行跨平台异步文件I / O.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆