Hacer E / S de socket de manera eficiente se ha resuelto con kqueue, epoll, puertos de finalización de E / S y similares. Hacer E / S de archivos asincrónicas es una especie de llegada tardía (aparte de las E / S superpuestas de Windows y el soporte temprano de Solaris para posix AIO).
Si está buscando hacer E / S de socket, probablemente sea mejor que use uno de los mecanismos anteriores.
El objetivo principal de AIO es, por tanto, resolver el problema de la E / S de disco asíncrona. Es muy probable que esta sea la razón por la que Mac OS X solo admite AIO para archivos normales y no sockets (ya que kqueue lo hace mucho mejor de todos modos).
Las operaciones de escritura generalmente se almacenan en caché por el kernel y se eliminan en un momento posterior. Por ejemplo, cuando el cabezal de lectura de la unidad pasa por la ubicación donde se va a escribir el bloque.
Sin embargo, para las operaciones de lectura, si desea que el kernel priorice y ordene sus lecturas, AIO es realmente la única opción. He aquí por qué el kernal puede (teóricamente) hacerlo mejor que cualquier aplicación de nivel de usuario:
- El kernel ve todas las E / S del disco, no solo los trabajos de disco de las aplicaciones, y puede ordenarlos a nivel global
- El kernel (puede) saber dónde está el cabezal de lectura del disco y puede elegir los trabajos de lectura que le transmita en el orden óptimo, para mover el cabezal la distancia más corta
- El kernel puede aprovechar la cola de comandos nativa para optimizar aún más sus operaciones de lectura
- Es posible que pueda realizar más operaciones de lectura por llamada al sistema usando lio_listio () que con readv (), especialmente si sus lecturas no son (lógicamente) contiguas, lo que ahorra una pequeña parte de la sobrecarga de llamadas del sistema.
- Su programa puede ser un poco más simple con AIO ya que no necesita un hilo adicional para bloquear en una llamada de lectura o escritura.
Dicho esto, posix AIO tiene una interfaz bastante incómoda, por ejemplo:
- El único medio eficiente y bien soportado de devoluciones de llamada de eventos es a través de señales, lo que dificulta su uso en una biblioteca, ya que significa usar números de señal del espacio de nombres de señal global del proceso. Si su sistema operativo no admite señales en tiempo real, también significa que debe recorrer todas sus solicitudes pendientes para averiguar cuál terminó realmente (este es el caso de Mac OS X, por ejemplo, no de Linux). La captura de señales en un entorno de subprocesos múltiples también crea algunas restricciones complicadas. Por lo general, no puede reaccionar al evento dentro del controlador de señales, pero debe generar una señal, escribir en una tubería o usar signalfd () (en Linux).
- lio_suspend () tiene los mismos problemas que select (), no escala muy bien con la cantidad de trabajos.
- lio_listio (), tal como se implementó, tiene un número bastante limitado de trabajos que puede pasar, y no es trivial encontrar este límite de manera portátil. Debe llamar a sysconf (_SC_AIO_LISTIO_MAX), que puede fallar, en cuyo caso puede usar la definición AIO_LISTIO_MAX, que no está necesariamente definida, pero luego puede usar 2, que se define como compatible con garantía.
En cuanto a la aplicación del mundo real que usa posix AIO, puede echar un vistazo a lighttpd (lighty), que también publicó una medición de rendimiento al presentar el soporte.
La mayoría de las plataformas posix soportan posix AIO por ahora (Linux, BSD, Solaris, AIX, tru64). Windows lo admite a través de su E / S de archivos superpuestos. Tengo entendido que solo Solaris, Windows y Linux realmente admiten async. E / S de archivos hasta el controlador, mientras que los otros sistemas operativos emulan el archivo async. E / S con subprocesos del kernel. Linux es la excepción, su implementación posix AIO en glibc emula operaciones asíncronas con subprocesos de nivel de usuario, mientras que su interfaz nativa de E / S asíncrona (io_submit (), etc.) es verdaderamente asíncrona hasta el controlador, asumiendo que el controlador lo admite. .
Creo que es bastante común entre los sistemas operativos no admitir posix AIO para ningún fd, pero restringirlo a archivos normales.