Question

Il existe des pages dispersées sur le Web qui décrivent les fonctions POSIX AIO de manière très détaillée. Aucun d'entre eux sont terriblement récents. Ce n'est pas clair ce qu'ils décrivent exactement. Par exemple, le & Quotient officiel & Quot; (?) site Web pour la prise en charge des entrées / sorties asynchrones dans le noyau Linux ici indique que sockets don ne fonctionne pas, mais le " aio.h " Les pages de manuel de mon poste de travail Ubuntu 8.04.1 semblent toutes impliquer que cela fonctionne pour des descripteurs de fichier arbitraires. Ensuite, il y a un autre projet qui semble fonctionner au niveau de la couche de la bibliothèque avec encore moins de documentation.

je voudrais savoir:

  • Quel est le but de POSIX AIO? Étant donné que l'exemple le plus évident d'une implémentation que je peux trouver indique qu'il ne prend pas en charge les sockets, tout cela me semble étrange. Est-ce juste pour les E / S de disque asynchrone? Si oui, pourquoi l’API hyper-générale? Sinon, pourquoi les entrées / sorties sur disque sont-elles la première chose qui a été attaquée?
  • Où se trouvent les exemples complets de programmes POSIX AIO que je peux consulter?
  • Est-ce que quelqu'un l'utilise réellement, pour de vrai?
  • Quelles plates-formes prennent en charge POSIX AIO? Quelles sont les parties qu'ils soutiennent? Est-ce que quelqu'un supporte vraiment le & Quot; Toute entrée / sortie à une FD & Quot; que <aio.h> semble promettre?

Les autres mécanismes de multiplexage à ma disposition sont parfaitement bons, mais les fragments d’informations aléatoires qui circulent me rendent curieux.

Était-ce utile?

La solution

Les E / S réseau ne constituent pas une priorité pour AIO car toutes les personnes qui écrivent des serveurs réseau POSIX utilisent une approche non bloquante basée sur les événements. L'ancien style Java & "; Des milliards de threads bloquants &"; approche suce horriblement.

Les E / S d’écriture de disque sont déjà mises en mémoire tampon et les E / S de lecture de disque peuvent être préchargées dans la mémoire tampon à l’aide de fonctions comme posix_fadvise. Cela laisse les E / S de disque directes sans tampon comme le seul objectif utile pour AIO.

Les entrées / sorties directes et non mises en mémoire 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 entrées / sorties sur disque.

Ainsi, à la fin, POSIX AIO se trouve dans la position de ne servir aucun objectif utile . Ne l'utilisez pas.

Autres conseils

La gestion efficace des E / S de socket a été résolue avec kqueue, epoll, les ports d’achèvement d’IO et autres. Faire des E / S sur fichiers asynchrones est un peu tardif (à part le support précoce des E / S superposées de Windows et la prise en charge précoce de solaris pour AIO posix).

Si vous souhaitez effectuer des E / S de socket, il vaut probablement mieux utiliser l'un des mécanismes ci-dessus.

L’objectif principal de l’AIO est donc de résoudre le problème des E / S de disque asynchrones. C’est très probablement la raison pour laquelle Mac OS X ne prend en charge que AIO pour les fichiers normaux, et non les sockets (car kqueue le fait bien mieux de toute façon).

Les opérations d'écriture sont généralement mises en cache par le noyau et effacé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 donne la priorité et ordonne vos lectures, AIO est vraiment la seule option. Voici pourquoi kernal peut (théoriquement) le faire mieux que n’importe quelle application de niveau utilisateur:

  • Le noyau voit toutes les E / S de disque, pas seulement les tâches de disque de vos applications, et peut les commander au niveau mondial
  • Le noyau (peut) savoir où se trouve la tête de lecture du disque et peut sélectionner les tâches de lecture que vous lui transmettez dans un ordre optimal afin de déplacer la tête à la distance la plus courte
  • Le noyau peut tirer parti de la mise en file d'attente des commandes natives pour optimiser vos opérations de lecture / li>
  • Vous pourrez peut-être émettre plus d'opérations de lecture par appel système à l'aide de lio_listio () qu'à l'aide de readv (), en particulier si vos lectures ne sont pas (logiquement) contiguës, ce qui vous évite un temps système d'appels système
  • .
  • Votre programme est peut-être un peu plus simple avec AIO car vous n'avez pas besoin d'un thread supplémentaire pour bloquer un appel en lecture ou en écriture.

Cela dit, posix AIO possède une interface assez maladroite, par exemple:

  • L'unique moyen de rappel d'événement efficace et bien pris en charge consiste à utiliser des signaux, ce qui rend son utilisation difficile dans une bibliothèque, car cela implique d'utiliser des numéros de signal provenant de l'espace de nom de signal global du processus. Si votre système d'exploitation ne prend pas en charge les signaux en temps réel, cela signifie également que vous devez parcourir toutes vos demandes en attente pour déterminer celle qui est réellement terminée (c'est le cas de Mac OS X par exemple, pas de Linux). Catching signaux dans un environnement multi-thread fait également des restrictions délicates. Vous ne pouvez généralement pas réagir à l'événement à l'intérieur du gestionnaire de signaux, mais vous devez générer un signal, écrire dans un tube ou utiliser signalfd () (sous Linux).
  • lio_suspend () a les mêmes problèmes que select (), il ne s’adapte pas très bien au nombre de tâches.
  • lio_listio (), tel qu’implémenté, a un nombre assez limité d’emplois que vous pouvez transmettre, et il n’est pas anodin de trouver cette limite de manière portable. Vous devez appeler sysconf (_SC_AIO_LISTIO_MAX), ce qui peut échouer. Dans ce cas, vous pouvez utiliser la définition AIO_LISTIO_MAX, qui ne sont pas nécessairement définies, mais vous pouvez également utiliser 2, qui est défini comme garanti pour être pris en charge.

En ce qui concerne les applications réelles utilisant posix AIO, vous pouvez jeter un oeil à lighttpd (lighty), qui a également publié un mesure de la performance lors de l'introduction du support.

La plupart des plates-formes posix prennent désormais en charge le posix AIO (Linux, BSD, Solaris, AIX, tru64). Windows le prend en charge via ses entrées / sorties de fichiers superposées. Je crois comprendre que seuls Solaris, Windows et Linux prennent réellement en charge l’async. fichier I / O jusqu'au pilote, tandis que les autres systèmes d'exploitation émulent l'async. I / O avec les threads du noyau. Linux étant l'exception, son implémentation posix AIO dans glibc émule les opérations asynchrones avec des threads de niveau utilisateur, alors que son interface d'ES asynchrone native (io_submit (), etc.) est vraiment asynchrone jusqu'au pilote, à supposer que ce dernier le supporte. .

Je crois que c'est assez communparmi les systèmes d’exploitation de ne pas prendre en charge posix AIO pour n’importe quel fichier fd, mais de le limiter aux fichiers normaux.

Un développeur de 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, des requêtes aio_write ou aio_read envoyées à ce thread. >

Il est également 'real' aio - supporté par le niveau du noyau (besoin de libaio pour cela, voir l’appel de io_submit http://linux.die.net/man/2/io_submit ); également besoin de O_DIRECT pour cela (peut ne pas être supporté par tous les systèmes de fichiers, mais les principaux le supportent)

voir ici:

http://lse.sourceforge.net/io/aio.html

http://linux.die.net/man/2/io_submit

Différence entre POSIX AIO et libaio sous Linux?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top