Как автор предлагаемого Boost.AFIO, который может использовать POSIX AIO, я настоятельно рекомендую не использовать POSIX AIO. Я вряд ли одинок в этом мнении, @arvid аналогично против: http://blog.libtorrent.org/2012/10/asynchronous-disk-io/. Сам API плохо разработан и, как результат, плохо сказывается на нагрузке, если вы не используете альтернативы или расширения для ОС, такие как BSD kqueues. POSIX AIO практически бесполезен как есть.
Кроме того, вызовы AIO не являются безопасными для Linux, что вы, вероятно, используете. Это связано с тем, что в Linux они реализованы в пользовательском пространстве, используя эмуляцию на основе threadpool. В BSD вызовы AIO имеют собственный интерфейс syscall ядра, но в ядре включается - да, вы догадались - эмуляция на основе потока, если только O_DIRECT не включен.
Таким образом, вы намного лучше используете POSIX, просто используя threadpool, если все ваши данные не совпадают с O_DIRECT. Если O_DIRECT действительно всегда включен, Linux предоставляет специальный API-интерфейс ядра, подробно описанный в http://man7.org/linux/man-pages/man2/io_submit.2.html, который довольно эффективен, и на BSD , если вы замените обработку сигналов с помощью BSD kqueues (https://www.freebsd.org/cgi/man.cgi?kqueue, см. EVFILT_AIO), то с помощью функций O_DIRECT также можно масштабировать, лучше, чем threadpool.
Использование обработки завершенного сигнала на ЛЮБОЙ платформе POSIX имеет ужасный производительность. AFIO v2 предоставляет общий POSIX AIO-сервер, и он ужасен, ужасен, ужасен. Избегайте, как чума.
Обратите внимание, что конструкция синхронного API с потоком переносима, хорошо масштабируется для большинства случаев использования, и это то, что я (и, действительно, arvid) рекомендовал бы всем без особых специальных потребностей, таких как создание бэкэнда базы данных, где вам нужно очень жесткое управление физический уровень хранения, и ничего, кроме O_DIRECT | O_SYNC, не является вариантом.
Хорошо, все, что сказал, если вы действительно хотите использовать сигнал управляемой AIO, я предполагаю, что это потому, что вы хотите мультиплекс файла ввод/вывод с не-файлом я/о вещах, и поэтому вы можете 't использовать aio_suspend(), который является надлежащим API для этого. То, как AFIO v2 справляется с этим, - использовать сигнал реального времени для прерывания aio_suspend(), когда необходимо обработать что-то не связанное с aio, затем его можно обработать и перезапустить aio_suspend(). Вам нужно быть очень осторожным в обработке рас и тупиков, и вам нужно тщательно маскировать и разоблачать сигнал для потока, вызывающего aio_suspend(), чтобы сигнал в реальном времени не потерялся, и вы потеряли пробуждение. В целом, это не стоит для типично гораздо более низкой производительности ввода/вывода, которую вы получаете через threadpool + синхронные API.
Из [страницы руководства 'aio_read'] (http://man7.org/linux/man-pages/man3/aio_read.3.html):« Одновременные операции ввода-вывода, указывающие одну и ту же структуру 'aiocb', производят неопределенные результаты ". Если сигнал возникает при выполнении другого вызова AIO с использованием той же структуры управления, это приведет к проблемам. Если вы используете отдельную структуру управления и отдельные буферы, это должно быть безопасно, я * думаю *. Я не знаю, будут ли проблемы с сигнализацией AIO, если запрос будет завершен немедленно. –
Не могли бы вы использовать отдельный поток, принимающий сигналы, используя, например, [ 'Sigwaitinfo()'] (http://man7.org/linux/man-pages/man2/sigwaitinfo.2.html)?Таким образом, вы могли бы выделить новую структуру управления (или использовать мьютексы), чтобы избежать использования уже существующей структуры управления? –