Как выполнить Межплатформенный Асинхронный Файловый ввод-вывод в C++

Я пишу, что приложение должно использовать большие аудио мультиобразцы, обычно приблизительно 50 МБ в размере. Один файл содержит приблизительно 80 отдельных коротких аудиозаписей, которые могут быть воспроизведены моим приложением в любое время. Поэтому все аудиоданные загружаются в память для быстрого доступа.

Однако при загрузке одного из этих файлов, может потребоваться много секунд для помещения в память, потому что я должен считать большой объем данных с ifstream, имея в виду мою программу, GUI временно замораживается. Я попробовал размещение в ОЗУ мой файл, но это вызывает огромные пики нагрузки ЦП и путаницу аудио каждый раз, когда я должен перейти в другую область файла, который не приемлем.

Таким образом, это привело меня думать, что выполнение Асинхронного чтения файла решит мою проблему, которая является данными, читается в другом процессе и вызывает функцию на завершении. Это должно быть и совместимо для Mac OS X и Windows и в C++.

Править: Не хочу пользоваться библиотекой Boost, потому что я хочу сохранить небольшую кодовую базу.

12
задан Cœur 29 April 2017 в 16:51
поделиться

2 ответа

boost имеет библиотеку asio, которой я раньше не пользовался (ее нет в списке одобренных НАСА сторонних библиотек).

Мой собственный подход заключался в том, чтобы дважды написать код чтения файла, один раз для Windows, один раз для API POSIX aio, а затем просто выбрать правильный код для связи.

Для Windows используйте OVERLAPPED (вы должны включить его в вызове CreateFile, а затем передать структуру OVERLAPPED при чтении). Вы можете либо установить событие при завершении (ReadFile), либо вызвать обратный вызов завершения (ReadFileEx). Возможно, вам потребуется изменить основной цикл обработки событий, чтобы использовать MsgWaitForMultipleObjectsEx, чтобы вы могли либо дождаться событий ввода-вывода, либо разрешить выполнение обратных вызовов в дополнение к получению сообщений окна WM_. В MSDN есть документация по этим функциям.

Для Linux есть либо fadvise и epoll, которые будут использовать кеш с опережающим чтением, либо aio_read, который разрешит фактические запросы асинхронного чтения. По завершении запроса вы получите сигнал, который следует использовать для публикации сообщения XWindows и пробуждения цикла обработки событий.

Оба они немного отличаются друг от друга в деталях, но общий эффект тот же - вы запрашиваете чтение, которое завершается в фоновом режиме, а затем ваш цикл отправки событий просыпается по завершении ввода-вывода.

10
ответ дан 2 December 2019 в 21:43
поделиться

Библиотека Boost.Asio имеет ограниченную реализацию операций асинхронного файлового ввода-вывода (только оболочка Windows для HANDLE), поэтому она вам не подходит. См. Также этот вопрос.

Вы можете легко реализовать собственное асинхронное чтение, используя стандартные потоки и библиотеку Boost.Thread (или поддержку потоков, специфичных для платформы).

2
ответ дан 2 December 2019 в 21:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: