AIO(7) Miscellaneous Information Manual AIO(7) NOM aio - Vue d'ensemble des entrees-sorties (E/S) asynchrones POSIX DESCRIPTION L'interface d'E/S asynchrones (AIO pour << asynchronous I/O >>) POSIX permet aux applications de declencher une ou plusieurs operations d'E/S realisees de facon asynchrone (c'est-a-dire en arriere-plan). La fin d'une operation d'E/S peut etre notifiee a l'application de differentes facons au choix : distribution d'un signal, instanciation d'un thread ou absence de notification. L'interface AIO POSIX est composee des fonctions suivantes : aio_read(3) Placer en file d'attente une requete de lecture. C'est l'equivalent asynchrone de read(2). aio_write(3) Placer en file d'attente une requete d'ecriture. C'est l'equivalent asynchrone de write(2). aio_fsync(3) Placer en file d'attente une requete de synchronisation pour des operations d'E/S sur un descripteur de fichier. C'est l'equivalent asynchrone de fsync(2) et fdatasync(2). aio_error(3) Obtenir l'etat d'erreur d'une requete d'E/S placee en file d'attente. aio_return(3) Obtenir l'etat de retour d'une requete d'E/S terminee. aio_suspend(3) Suspendre l'appelant jusqu'a la fin d'une ou plusieurs requetes d'E/S d'un ensemble indique. aio_cancel(3) Essayer d'annuler des requetes d'E/S en cours sur un descripteur de fichier indique. lio_listio(3) Placer en file d'attente plusieurs requetes d'E/S a partir d'un seul appel de fonction. La structure aiocb (<< asynchronous I/O control block >>, ou bloc de controle d'E/S asynchrones) definit les parametres de controle d'une operation d'E/S. Un argument de ce type est utilise avec toutes les fonctions precedentes. Cette structure est de la forme suivante : #include struct aiocb { /* L'ordre de ces champs depend de l'implementation */ int aio_fildes; /* Descripteur de fichier */ off_t aio_offset; /* Position dans le fichier */ volatile void *aio_buf; /* Emplacement du tampon */ size_t aio_nbytes; /* Longueur de transfert */ int aio_reqprio; /* Priorite de requete */ struct sigevent aio_sigevent; /* Methode de notification */ int aio_lio_opcode; /* Operation a realiser ; lio_listio() seulement */ /* Divers champs internes a l'implementation ne sont pas montres */ }; /* Codes operatoires pour << aio_lio_opcode >> : */ enum { LIO_READ, LIO_WRITE, LIO_NOP }; Les membres de cette structure sont les suivants : aio_fildes Le descripteur du fichier sur lequel les operations d'E/S sont a realiser. aio_offset La position dans le fichier ou les operations d'E/S sont a realiser. aio_buf Le tampon utilise pour le transfert de donnees des operations de lecture ou d'ecriture. aio_nbytes La taille du tampon pointe par aio_buf. aio_reqprio Valeur a soustraire de la priorite temps-reel du thread de l'appelant pour determiner la priorite d'execution de cette requete d'E/S (consultez pthread_setschedparam(3)). La valeur indiquee doit etre entre 0 et la valeur renvoyee par sysconf(_SC_AIO_PRIO_DELTA_MAX). Ce champ est ignore lors des operations de synchronisation de fichier. aio_sigevent Structure indiquant comment l'appelant sera notifie de la fin d'une operation d'E/S asynchrone. Les valeurs de aio_sigevent.sigev_notify peuvent etre SIGEV_NONE, SIGEV_SIGNAL et SIGEV_THREAD. Consultez sigevent(3type) pour plus de precisions. aio_lio_opcode Le type d'operation a realiser, utilise seulement pour lio_listio(3). En plus des fonctions standard precedentes, la bibliotheque C du projet GNU fournit l'extension suivante a l'API AIO POSIX : aio_init(3) Configurer les parametres pour regler le comportement de l'implementation AIO POSIX de la glibc. ERREURS EINVAL Le champ aio_reqprio de la structure aiocb etait inferieur a 0 ou superieur a la limite renvoyee par l'appel sysconf(_SC_AIO_PRIO_DELTA_MAX). NORMES POSIX.1-2008. HISTORIQUE POSIX.1-2001. glibc 2.1. NOTES Il est conseille de mettre a zero le tampon de bloc de controle avant utilisation (consultez memset(3)). Le tampon de bloc de controle et le tampon pointe par aio_buf ne doivent pas etre modifies pendant l'execution d'une operation d'E/S. Ces tampons doivent rester valables jusqu'a la fin de l'operation d'E/S. Les operations de lecture ou d'ecriture asynchrones simultanees qui utilisent la meme structure aiocb produisent des resultats indefinis. L'actuelle implementation AIO POSIX de Linux est fournie en espace utilisateur par la glibc. De nombreuses limites existent, en particulier le maintien de plusieurs threads pour realiser des operations d'E/S est tres couteux et monte mal en charge. L'implementation d'E/S asynchrones basee sur l'etat de la machine est en travaux depuis un moment sur le noyau (consultez io_submit(2), io_setup(2), io_cancel(2), io_destroy(2), io_getevents(2)), mais cette implementation n'a pas encore atteint le niveau ou l'implementation AIO POSIX peut etre entierement reimplementee en utilisant les appels systeme du noyau. EXEMPLES Le programme suivant ouvre chaque fichier nomme en argument de sa ligne de commande et place une requete sur le descripteur de fichier dans la file avec aio_read(3). Le programme boucle ensuite, en surveillant periodiquement toutes les operations d'E/S en cours avec aio_error(3). Chaque requete d'E/S est configuree pour fournir une notification en distribuant un signal. Quand toutes les requetes d'E/S sont terminees, le programme recupere leur etat avec aio_return(3). Le signal SIGQUIT (cree en tapant Controle-\) provoque la demande d'annulation de chaque requete en cours avec aio_cancel(3). Voici un exemple de ce qui pourrait etre affiche lors de l'execution de ce programme. Dans cet exemple, le programme place en file d'attente deux requetes sur l'entree standard et deux lignes de saisie contenant << abc >> et << x >> y repondent. $ ./a.out /dev/stdin /dev/stdin; /dev/stdin ouvert sur le descripteur 3 /dev/stdin ouvert sur le descripteur 4 aio_error(): pour la requete 0 (descripteur 3) : En cours pour la requete 1 (descripteur 4) : En cours abc Signal de fin d'E/S recu aio_error(): pour la requete 0 (descripteur 3) : E/S reussie pour la requete 1 (descripteur 4) : En cours aio_error(): pour la requete 1 (descripteur 4) : En cours x Signal de fin d'E/S recu aio_error(): pour la requete 1 (descripteur 4) : E/S reussie Toutes les requetes d'E/S sont terminees aio_return(): pour la requete 0 (descripteur 3) : 4 pour la requete 1 (descripteur 4) : 2 Source du programme #include #include #include #include #include #include #include #include #define BUF_SIZE 20 /* Size of buffers for read operations */ struct ioRequest { /* Application-defined structure for tracking I/O requests */ int reqNum; int status; struct aiocb *aiocbp; }; static volatile sig_atomic_t gotSIGQUIT = 0; /* On delivery of SIGQUIT, we attempt to cancel all outstanding I/O requests */ static void /* Handler for SIGQUIT */ quitHandler(int sig) { gotSIGQUIT = 1; } #define IO_SIGNAL SIGUSR1 /* Signal used to notify I/O completion */ static void /* Handler for I/O completion signal */ aioSigHandler(int sig, siginfo_t *si, void *ucontext) { if (si->si_code == SI_ASYNCIO) { write(STDOUT_FILENO, "I/O completion signal received\n", 31); /* The corresponding ioRequest structure would be available as struct ioRequest *ioReq = si->si_value.sival_ptr; and the file descriptor would then be available via ioReq->aiocbp->aio_fildes */ } } int main(int argc, char *argv[]) { struct sigaction sa; int s; int numReqs; /* Total number of queued I/O requests */ int openReqs; /* Number of I/O requests still in progress */ if (argc < 2) { fprintf(stderr, "Usage: %s ...\n", argv[0]); exit(EXIT_FAILURE); } numReqs = argc - 1; /* Allocate our arrays. */ struct ioRequest *ioList = calloc(numReqs, sizeof(*ioList)); if (ioList == NULL) err(EXIT_FAILURE, "calloc"); struct aiocb *aiocbList = calloc(numReqs, sizeof(*aiocbList)); if (aiocbList == NULL) err(EXIT_FAILURE, "calloc"); /* Establish handlers for SIGQUIT and the I/O completion signal. */ sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sa.sa_handler = quitHandler; if (sigaction(SIGQUIT, &sa, NULL) == -1) err(EXIT_FAILURE, "sigaction"); sa.sa_flags = SA_RESTART | SA_SIGINFO; sa.sa_sigaction = aioSigHandler; if (sigaction(IO_SIGNAL, &sa, NULL) == -1) err(EXIT_FAILURE, "sigaction"); /* Open each file specified on the command line, and queue a read request on the resulting file descriptor. */ for (size_t j = 0; j < numReqs; j++) { ioList[j].reqNum = j; ioList[j].status = EINPROGRESS; ioList[j].aiocbp = &aiocbList[j]; ioList[j].aiocbp->aio_fildes = open(argv[j + 1], O_RDONLY); if (ioList[j].aiocbp->aio_fildes == -1) err(EXIT_FAILURE, "open"); printf("opened %s on descriptor %d\n", argv[j + 1], ioList[j].aiocbp->aio_fildes); ioList[j].aiocbp->aio_buf = malloc(BUF_SIZE); if (ioList[j].aiocbp->aio_buf == NULL) err(EXIT_FAILURE, "malloc"); ioList[j].aiocbp->aio_nbytes = BUF_SIZE; ioList[j].aiocbp->aio_reqprio = 0; ioList[j].aiocbp->aio_offset = 0; ioList[j].aiocbp->aio_sigevent.sigev_notify = SIGEV_SIGNAL; ioList[j].aiocbp->aio_sigevent.sigev_signo = IO_SIGNAL; ioList[j].aiocbp->aio_sigevent.sigev_value.sival_ptr = &ioList[j]; s = aio_read(ioList[j].aiocbp); if (s == -1) err(EXIT_FAILURE, "aio_read"); } openReqs = numReqs; /* Loop, monitoring status of I/O requests. */ while (openReqs > 0) { sleep(3); /* Delay between each monitoring step */ if (gotSIGQUIT) { /* On receipt of SIGQUIT, attempt to cancel each of the outstanding I/O requests, and display status returned from the cancelation requests. */ printf("got SIGQUIT; canceling I/O requests: \n"); for (size_t j = 0; j < numReqs; j++) { if (ioList[j].status == EINPROGRESS) { printf(" Request %zu on descriptor %d:", j, ioList[j].aiocbp->aio_fildes); s = aio_cancel(ioList[j].aiocbp->aio_fildes, ioList[j].aiocbp); if (s == AIO_CANCELED) printf("I/O canceled\n"); else if (s == AIO_NOTCANCELED) printf("I/O not canceled\n"); else if (s == AIO_ALLDONE) printf("I/O all done\n"); else perror("aio_cancel"); } } gotSIGQUIT = 0; } /* Check the status of each I/O request that is still in progress. */ printf("aio_error():\n"); for (size_t j = 0; j < numReqs; j++) { if (ioList[j].status == EINPROGRESS) { printf(" for request %zu (descriptor %d): ", j, ioList[j].aiocbp->aio_fildes); ioList[j].status = aio_error(ioList[j].aiocbp); switch (ioList[j].status) { case 0: printf("I/O succeeded\n"); break; case EINPROGRESS: printf("In progress\n"); break; case ECANCELED: printf("Canceled\n"); break; default: perror("aio_error"); break; } if (ioList[j].status != EINPROGRESS) openReqs--; } } } printf("All I/O requests completed\n"); /* Check status return of all I/O requests. */ printf("aio_return():\n"); for (size_t j = 0; j < numReqs; j++) { ssize_t s; s = aio_return(ioList[j].aiocbp); printf(" for request %zu (descriptor %d): %zd\n", j, ioList[j].aiocbp->aio_fildes, s); } exit(EXIT_SUCCESS); } VOIR AUSSI io_cancel(2), io_destroy(2), io_getevents(2), io_setup(2), io_submit(2), aio_cancel(3), aio_error(3), aio_init(3), aio_read(3), aio_return(3), aio_write(3), lio_listio(3) "Asynchronous I/O Support in Linux 2.5", Bhattacharya, Pratt, Pulavarty, and Morgan, Proceedings of the Linux Symposium, 2003, TRADUCTION La traduction francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot , Thomas Vincent et Jean- Pierre Giraud Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.18 8 fevrier 2026 AIO(7)