Hacer las conexiones de E/S de manera eficiente ha sido resuelto con kqueue, epoll, puertos de terminación IO y "me gusta". Hacer E/S de archivos asíncronos es una especie de punto de retraso (aparte de la E/S solapada de Windows y el soporte temprano de Solaris para POSIO AIO).
Si está buscando hacer E/S de socket, probablemente sea mejor que utilice 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 Mac OS X solo admita AIO para archivos regulares, y no para sockets (ya que de todos modos kqueue lo hace mucho mejor).
Las operaciones de escritura generalmente se guardan en la memoria 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 escribirá el bloque.
Sin embargo, para 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 meollo puede hacer (en teoría) que mejor que cualquier aplicación de nivel de usuario:
- que ve el núcleo de todos los discos S, no sólo sus empleos disco, I/aplicaciones, y pueden hacer pedidos a nivel mundial
- El kernel (puede) saber dónde está el cabezal de lectura del disco, y puede elegir los trabajos de lectura que le pasa en orden óptimo, para mover el cabezal la distancia más corta
- El kernel puede aprovechar native command queuing para optimizar sus operaciones de lectura más
- Es posible que pueda emitir más operaciones de lectura por llamada al sistema utilizando lio_listio() que con readv(), especialmente si y nuestras lecturas no son (lógicamente) contiguas, lo que ahorra un poco de sobrecarga de llamadas al 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, AIO posix tiene una interfaz bastante incómodo, por ejemplo:
- La única eficiente y bien soportado media de devoluciones de llamada de eventos son a través de señales, que hace que sea difícil de usar en una biblioteca, ya que significa usar números de señal del espacio de nombres de la 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 genera algunas restricciones difíciles. Por lo general, no puede reaccionar al evento dentro del controlador de señal, pero debe elevar una señal, escribir en un conducto o usar signalfd() (en Linux).
- lio_suspend() tiene los mismos problemas que select(), no se escala muy bien con el número de trabajos.
- lio_listio(), implementado tiene un número bastante limitado de trabajos que puede pasar, y no es trivial encontrar este límite de forma 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 garantizado para ser compatible.
En cuanto a la aplicación en el mundo real utilizando AIO POSIX, que podría echar un vistazo a lighttpd (lighty), que también registró una performance measurement cuando la introducción de apoyo.
La mayoría de las plataformas POSIX ahora admiten AIO posix (Linux, BSD, Solaris, AIX, tru64). Windows lo admite a través de su E/S de archivo superpuesto. Tengo entendido que solo Solaris, Windows y Linux realmente admiten asincrónicos. archivo de E/S hasta el controlador, mientras que los otros sistemas operativos emulan la asincrónica. E/S con hilos del kernel. Linux es la excepción, su implementación POSIO AIO en glibc emula operaciones asincrónicas con subprocesos de nivel de usuario, mientras que su interfaz de E/S asincrónica nativa (io_submit() etc.) es verdaderamente asíncrona hasta el controlador, suponiendo que el controlador lo soporte .
Creo que es bastante común entre los sistemas operativos no admitir posix AIO para cualquier fd, pero restringirlo a los archivos normales.
Lo sobre leer/escribir desde sistemas de archivos de red (NFS, Samba)? –
bien. Tengo varios escritores tontos grandes que, si los dejo ir al caché, golpearán dirty_ratio en picos, bloqueando a todos los demás. Si solo uso IO directo en ellos, es demasiado lento. Si tuviera solo 1 hilo, podría hacerlo solo, pero será difícil soportar diferentes prioridades IO en 1 banda de rodadura. AIO + CFQ realmente parece una buena combinación, si AIO trabajó –
No estoy de acuerdo. La E/S de disco tiende a almacenarse en el búfer pero puede estar bloqueando. Al sondear un archivo FD, siempre informa que el FD es legible, incluso cuando se bloqueará. Esto hace que sea imposible realizar operaciones sin bloqueo en los archivos del disco de una manera eficaz, a menos que uno use hilos o AIO. – Hongli