Ефективне введення / виведення сокета вирішено за допомогою kqueue, epoll, портів для завершення IO тощо. Асинхронний файл вводу / виводу є своєрідним пізнім (крім перекритого вікном вводу / виводу та ранньої підтримки для posix AIO).
Якщо ви шукаєте робити введення / виведення сокета, вам, мабуть, краще скористатися одним із перерахованих вище механізмів.
Основна мета AIO - отже, вирішити проблему асинхронного дискового вводу / виводу. Це, швидше за все, тому Mac OS X підтримує лише AIO для звичайних файлів, а не сокетів (оскільки kqueue все одно робить це набагато краще).
Операції запису, як правило, кешуються ядром і видаляються пізніше. Наприклад, коли зчитувана головка накопичувача проходить повз місце, де слід записувати блок.
Однак для операцій з читанням, якщо ви хочете, щоб ядро надало пріоритет і замовляло свої зчитування, AIO - це справді єдиний варіант. Ось чому ядро може (теоретично) зробити це краще, ніж будь-яке додаток на рівні користувача:
- Ядро бачить усі дискові введення / виведення, а не тільки ваші завдання на диску, і може замовити їх на глобальному рівні
- Ядро (можливо) знає, де знаходиться головка зчитування диска, і може вибирати завдання для читання, які ви передаєте йому, в оптимальному порядку, щоб перемістити голову на найкоротші відстані
- Ядро може скористатися натурною чергою команд, щоб додатково оптимізувати свої операції зчитування
- Можливо, ви зможете здійснити більше операцій зчитування за системний виклик за допомогою lio_listio (), ніж для readv (), особливо якщо ваші читання не є (логічно) суміжними, зберігаючи крихітний біт накладних системних викликів.
- Ваша програма може бути трохи простішою з AIO, оскільки вам не потрібна додаткова нитка для блокування дзвінка читання або запису.
Однак, posix AIO має досить незручний інтерфейс, наприклад:
- Єдиним ефективним та добре підтримуваним способом зворотних викликів подій є сигнали, що ускладнює їх використання в бібліотеці, оскільки це означає використання сигнальних номерів з просторового простору імен сигналів процесу. Якщо ваша ОС не підтримує сигнали в режимі реального часу, це також означає, що вам доведеться переглядати всі свої непогашені запити, щоб з'ясувати, який з них фактично закінчений (це стосується, наприклад, Mac OS X, а не Linux). Ловля сигналів у багатопотоковому середовищі також передбачає деякі складні обмеження. Зазвичай ви не можете реагувати на подію всередині обробника сигналів, але вам потрібно підняти сигнал, записати в трубку або використовувати signalfd () (на Linux).
- lio_suspend () має ті самі проблеми, що і select (), але він не дуже добре розширюється з кількістю завдань.
- lio_listio (), оскільки впроваджена має досить обмежену кількість завдань, які ви можете передати, і не тривіально знайти цю межу портативно. Вам потрібно зателефонувати на sysconf (_SC_AIO_LISTIO_MAX), який може не вдатися, і в цьому випадку ви можете використовувати визначення AIO_LISTIO_MAX, які не обов'язково визначаються, але тоді ви можете використовувати 2, які визначаються як гарантовано підтримувані.
Що стосується додатків у реальному світі, що використовують posix AIO, ви можете поглянути на lighttpd (lighty), який також розмістив вимірювання продуктивності при впровадженні підтримки.
На сьогоднішній день більшість платформ Posix підтримує posix AIO (Linux, BSD, Solaris, AIX, tru64). Windows підтримує його через перекритий файл вводу-виводу. Я розумію, що лише Solaris, Windows та Linux справді підтримують асинхронізацію. файли вводу / виводу до самого драйвера, тоді як інші ОС наслідують асинхронізацію. Введення / виведення з потоками ядра. Винятком є Linux, його реалізація posix AIO у glibc емулює операції async з потоками користувачів, тоді як його вбудований інтерфейс вводу / виводу async (io_submit () тощо) є справді асинхронним аж до драйвера, припускаючи, що драйвер підтримує його .
Я вважаю, що досить часто серед ОС працює не підтримувати позікс AIO для будь-якого fd, а обмежувати його звичайними файлами.