Des pages disséminées sur le Web décrivent les installations POSIX AIO avec plus ou moins de détails. Aucun d'eux n'est terriblement récent. On ne sait pas exactement ce qu'ils décrivent. Par exemple, le "officiel" (?) site Web pour le support des E/S asynchrones du noyau Linux ici dit que les sockets ne fonctionnent pas, mais les pages de manuel "aio.h" sur mon Ubuntu 8.04. 1 poste de travail semble tous impliquer qu'il fonctionne pour des descripteurs de fichiers arbitraires. Ensuite, il y a n autre projet qui semble fonctionner au niveau de la bibliothèque avec encore moins de documentation.
J'aimerais savoir:
<aio.h>
semble promettre?Les autres mécanismes de multiplexage à ma disposition sont parfaitement bons, mais les fragments aléatoires d'informations flottant là-bas m'ont rendu curieux.
Les E/S réseau ne sont pas une priorité pour AIO car tous ceux qui écrivent des serveurs réseau POSIX utilisent une approche non bloquante basée sur les événements. L'ancienne approche Java "milliards de threads de blocage" est horrible.
Les E/S d'écriture sur disque sont déjà mises en mémoire tampon et les E/S de lecture sur disque peuvent être prélues dans le tampon à l'aide de fonctions telles que posix_fadvise. Cela laisse des E/S de disque directes et sans tampon comme seul objectif utile pour AIO.
Les E/S directes et sans tampon ne sont vraiment utiles que pour les bases de données transactionnelles, et celles-ci ont tendance à écrire leurs propres threads ou processus pour gérer leurs E/S disque.
Donc, à la fin, cela laisse POSIX AIO dans la position de ne pas servir tout but utile. Ne l'utilisez pas.
Faire des E/S de socket efficacement a été résolu avec kqueue, epoll, IO ports d'achèvement et autres. Faire des E/S de fichiers asynchrones est une sorte de retard (en dehors du chevauchement des fenêtres I/O et solaris support précoce pour posix AIO).
Si vous cherchez à faire des E/S de socket, vous feriez probablement mieux d'utiliser l'un des mécanismes ci-dessus.
L'objectif principal d'AIO est donc de résoudre le problème des E/S sur disque asynchrone. C'est probablement la raison pour laquelle Mac OS X ne prend en charge AIO que pour les fichiers normaux, et non pour les sockets (car kqueue le fait tellement mieux de toute façon).
Les opérations d'écriture sont généralement mises en cache par le noyau et vidées ultérieurement. Par exemple, lorsque la tête de lecture du lecteur passe par l'emplacement où le bloc doit être écrit.
Cependant, pour les opérations de lecture, si vous voulez que le noyau priorise et ordonne vos lectures, AIO est vraiment la seule option. Voici pourquoi le kernal peut (théoriquement) faire mieux que n'importe quelle application de niveau utilisateur:
Cela dit, posix AIO a une interface assez maladroite, par exemple:
En ce qui concerne les applications réelles utilisant posix AIO, vous pouvez jeter un œil à lighttpd (lighty), qui a également publié un mesure des performances lors de l'introduction du support.
La plupart des plates-formes posix prennent désormais en charge posix AIO (Linux, BSD, Solaris, AIX, tru64). Windows le prend en charge via ses E/S de fichiers qui se chevauchent. D'après ce que je comprends, seuls Solaris, Windows et Linux prennent réellement en charge l'async. déposer les E/S jusqu'au pilote, tandis que les autres systèmes d'exploitation émulent l'async. E/S avec threads du noyau. Linux étant l'exception, son implémentation AIO posix dans la glibc émule des opérations asynchrones avec des threads de niveau utilisateur, tandis que son interface native d'E/S asynchrone (io_submit () etc.) est vraiment asynchrone jusqu'au pilote, en supposant que le pilote le supporte .
Je pense qu'il est assez courant parmi les systèmes d'exploitation de ne pas prendre en charge le posix AIO pour aucun fd, mais de le limiter aux fichiers ordinaires.
Un développeur libtorrent fournit un rapport à ce sujet: http://blog.libtorrent.org/2012/10/asynchronous-disk-io/
Il y a aio_write - implémenté dans la glibc; le premier appel de la fonction aio_read ou aio_write génère un certain nombre de threads en mode utilisateur, aio_write ou aio_read envoie des requêtes à ce thread, le thread procède à la lecture/écriture et à la fin, la réponse est envoyée au thread appelant bloqué.
Ther est également "réel" aio - pris en charge par le niveau du noyau (besoin de libaio pour cela, voir l'appel io_submit http://linux.die.net/man/2/io_submit ); nécessite également O_DIRECT pour cela (peut ne pas être pris en charge par tous les systèmes de fichiers, mais les principaux le prennent en charge)
vois ici: