Fare I / O socket in modo efficiente è stato risolto con kqueue, epoll, porte di completamento IO e simili. Fare I / O su file asincrono è una specie di arrivo in ritardo (a parte l'I / O sovrapposto di Windows e il supporto anticipato di Solaris per posix AIO).
Se stai cercando di fare I / O socket, probabilmente stai meglio usando uno dei meccanismi di cui sopra.
Lo scopo principale di AIO è quindi quello di risolvere il problema dell'I / O asincrono del disco. Questo è molto probabilmente il motivo per cui Mac OS X supporta AIO solo per i file normali e non per i socket (poiché kqueue lo fa molto meglio comunque).
Le operazioni di scrittura vengono in genere memorizzate nella cache dal kernel e cancellate in un secondo momento. Ad esempio, quando la testina di lettura dell'unità passa dalla posizione in cui deve essere scritto il blocco.
Tuttavia, per le operazioni di lettura, se vuoi che il kernel dia la priorità e ordini le tue letture, AIO è davvero l'unica opzione. Ecco perché il kernal può (teoricamente) farlo meglio di qualsiasi applicazione a livello utente:
- Il kernel vede tutto l'I / O del disco, non solo i lavori del disco delle applicazioni, e può ordinarli a livello globale
- Il kernel (può) sapere dove si trova la testina di lettura del disco e può scegliere i lavori di lettura che gli vengono trasmessi in ordine ottimale, per spostare la testina la distanza più breve
- Il kernel può trarre vantaggio dall'accodamento nativo dei comandi per ottimizzare ulteriormente le operazioni di lettura
- Potresti essere in grado di eseguire più operazioni di lettura per chiamata di sistema usando lio_listio () che con readv (), specialmente se le tue letture non sono (logicamente) contigue, risparmiando un po 'di overhead delle chiamate di sistema.
- Il tuo programma potrebbe essere leggermente più semplice con AIO poiché non hai bisogno di un thread aggiuntivo per bloccare in una chiamata di lettura o scrittura.
Detto questo, posix AIO ha un'interfaccia piuttosto scomoda, ad esempio:
- L'unico mezzo efficiente e ben supportato di callback di eventi è tramite segnali, il che lo rende difficile da usare in una libreria, poiché significa usare numeri di segnale dallo spazio dei nomi del segnale globale del processo. Se il tuo sistema operativo non supporta i segnali in tempo reale, significa anche che devi scorrere tutte le tue richieste in sospeso per capire quale è effettivamente terminata (questo è il caso di Mac OS X, ad esempio, non Linux). La cattura dei segnali in un ambiente multi-threading comporta anche alcune restrizioni complicate. Normalmente non puoi reagire all'evento all'interno del gestore del segnale, ma devi alzare un segnale, scrivere su una pipe o usare signalfd () (su linux).
- lio_suspend () ha gli stessi problemi di select (), non si adatta molto bene con il numero di lavori.
- lio_listio (), come implementato ha un numero abbastanza limitato di lavori che puoi passare, e non è banale trovare questo limite in modo portabile. Devi chiamare sysconf (_SC_AIO_LISTIO_MAX), che potrebbe fallire, nel qual caso puoi usare la definizione AIO_LISTIO_MAX, che non sono necessariamente definiti, ma poi puoi usare 2, che è definito come garantito per essere supportato.
Per quanto riguarda l'applicazione del mondo reale che utilizza posix AIO, potresti dare un'occhiata a lighttpd (lighty), che ha anche pubblicato una misurazione delle prestazioni quando si introduce il supporto.
La maggior parte delle piattaforme posix supporta posix AIO ormai (Linux, BSD, Solaris, AIX, tru64). Windows lo supporta tramite il suo file I / O sovrapposto. La mia comprensione è che solo Solaris, Windows e Linux supportano veramente l'asincronia. I / O dei file fino al driver, mentre gli altri sistemi operativi emulano il file async. I / O con thread del kernel. Linux è l'eccezione, la sua implementazione AIO posix in glibc emula operazioni asincrone con thread a livello utente, mentre la sua interfaccia I / O asincrona nativa (io_submit () ecc.) È veramente asincrona fino al driver, assumendo che il driver lo supporti .
Credo che sia abbastanza comune tra i sistemi operativi non supportare posix AIO per qualsiasi fd, ma limitarlo ai file normali.