Provided by: manpages-fr_3.32d0.2p4-1_all bug

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 <aiocb.h>

           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 champs de cette structure sont les suivants :

       aio_filedes     Le descripteur de 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(7)
                       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 les extensions suivantes a l'API AIO POSIX :

       aio_init(3)     Configurer  les  parametres pour regler le comportement
                       de l'implementation AIO POSIX de la glibc.

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.

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).

VERSIONS

       Les  interfaces  AIO  POSIX  sont  fournies  par  la  glibc  depuis  la
       version 2.1.

CONFORMIT'E

       POSIX.1-2001, POSIX.1-2008.

EXEMPLE

       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 <stdlib.h>
       #include <unistd.h>
       #include <stdio.h>
       #include <errno.h>
       #include <aio.h>
       #include <signal.h>

       #define BUF_SIZE 20     /* Taille des tampons pour les operations de lecture */

       #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)

       #define errMsg(msg)  do { perror(msg); } while (0)

       struct ioRequest {      /* Structure specifique a l'application
                                  pour suivre les requetes d'E/S */
           int           reqNum;
           int           status;
           struct aiocb *aiocbp;
       };

       static volatile sig_atomic_t gotSIGQUIT = 0;
                               /* Essayer d'annuler toutes les requetes d'E/S
                                  en cours lors de la reception d'un SIGQUIT */

       static void             /* Gestionnaire pour SIGQUIT */
       quitHandler(int sig)
       {
           gotSIGQUIT = 1;
       }

       #define IO_SIGNAL SIGUSR1   /* Signal pour notifier la fin d'E/S */

       static void                 /* Gestionnaire pour le signal de fin d'E/S */
       aioSigHandler(int sig, siginfo_t *si, void *ucontext)
       {
           write(STDOUT_FILENO, "Signal de fin d'E/S recu\n", 31);

           /* La structure ioRequest correspondante serait disponible en
                  struct ioRequest *ioReq = si->si_value.sival_ptr;
              et le descripteur de fichier serait alors disponible via
                  ioReq->aiocbp->aio_fildes */
       }

       int
       main(int argc, char *argv[])
       {
           struct ioRequest *ioList;
           struct aiocb *aiocbList;
           struct sigaction sa;
           int s, j;
           int numReqs;        /* Nombre total de requetes d'E/S dans la file */
           int openReqs;       /* Nombre de requetes d'E/S encore en cours */

           if (argc < 2) {
               fprintf(stderr, "Utilisation : %s <chemin> <chemin>...\n",
                       argv[0]);
               exit(EXIT_FAILURE);
           }

           numReqs = argc - 1;

           /* Allocation des tableaux */

           ioList = calloc(numReqs, sizeof(struct ioRequest));
           if (ioList == NULL)
               errExit("calloc");

           aiocbList = calloc(numReqs, sizeof(struct aiocb));
           if (aiocbList == NULL)
               errExit("calloc");

           /* Mise en place des gestionnaires pour SIGQUIT et le signal de fin d'E/S */

           sa.sa_flags = SA_RESTART;
           sigemptyset(&sa.sa_mask);

           sa.sa_handler = quitHandler;
           if (sigaction(SIGQUIT, &sa, NULL) == -1)
               errExit("sigaction");

           sa.sa_flags = SA_RESTART | SA_SIGINFO;
           sa.sa_sigaction = aioSigHandler;
           if (sigaction(IO_SIGNAL, &sa, NULL) == -1)
               errExit("sigaction");

           /* Ouverture de chaque fichier indique sur la ligne de commande, et mise en file
              d'attente d'une requete de lecture sur le descripteur de fichier correspondant */

           for (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)
                   errExit("open");
               printf("%s ouvert sur le descripteur %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)
                   errExit("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)
                   errExit("aio_read");
           }

           openReqs = numReqs;

           /* Boucle, surveillance de l'etat des requetes d'E/S */

           while (openReqs > 0) {
               sleep(3);       /* Delai entre chaque etape de surveillance */

               if (gotSIGQUIT) {

                   /* Lors de la reception de SIGQUIT, essayer d'annuler
                      toutes les requetes d'E/S en cours, et afficher
                      l'etat renvoye par les requetes d'annulation */

                   printf("reception de SIGQUIT ; annulation des requetes d'E/S : \n");

                   for (j = 0; j < numReqs; j++) {
                       if (ioList[j].status == EINPROGRESS) {
                           printf("    Requete %d sur le descripteur %d :", j,
                                   ioList[j].aiocbp->aio_fildes);
                           s = aio_cancel(ioList[j].aiocbp->aio_fildes,
                                   ioList[j].aiocbp);
                           if (s == AIO_CANCELED)
                               printf("E/S annulee\n");
                           else if (s == AIO_NOTCANCELED)
                                   printf("E/S non annulee\n");
                           else if (s == AIO_ALLDONE)
                               printf("E/S terminee\n");
                           else
                               errMsg("aio_cancel");
                       }
                   }

                   gotSIGQUIT = 0;
               }

               /* Verification de l'etat de toutes les
                  requetes d'E/S encore en cours */

               printf("aio_error():\n");
               for (j = 0; j < numReqs; j++) {
                   if (ioList[j].status == EINPROGRESS) {
                       printf("    pour la requete %d (descripteur %d) : ",
                               j, ioList[j].aiocbp->aio_fildes);
                       ioList[j].status = aio_error(ioList[j].aiocbp);

                       switch (ioList[j].status) {
                       case 0:
                           printf("E/S reussie\n");
                           break;
                       case EINPROGRESS:
                           printf("En cours\n");
                           break;
                       case ECANCELED:
                           printf("Annulee\n");
                           break;
                       default:
                           errMsg("aio_error");
                           break;
                       }

                       if (ioList[j].status != EINPROGRESS)
                           openReqs--;
                   }
               }
           }

           printf("Toutes les requetes d'E/S sont terminees\n");

           /* Verification de l'etat de retour de toutes les requetes d'E/S */

           printf("aio_return():\n");
           for (j = 0; j < numReqs; j++) {
               ssize_t s;

               s = aio_return(ioList[j].aiocbp);
               printf("    pour la requete %d (descripteur %d) : %ld\n",
                       j, ioList[j].aiocbp->aio_fildes, (long) 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),
       http://www.squid-cache.org/~adrian/Reprint-Pulavarty-OLS2003.pdf

COLOPHON

       Cette page fait partie de la publication 3.32 du projet man-pages
       Linux. Une description du projet et des instructions pour signaler des
       anomalies peuvent etre trouvees a l'adresse
       <URL:http://www.kernel.org/doc/man-pages/>.

TRADUCTION

       Depuis 2010, cette traduction est maintenue a l'aide de l'outil po4a
       <URL:http://po4a.alioth.debian.org/> par l'equipe de traduction
       francophone au sein du projet perkamon
       <URL:http://perkamon.alioth.debian.org/>.

       Veuillez signaler toute erreur de traduction en ecrivant a
       <debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
       paquet manpages-fr.

       Vous pouvez toujours avoir acces a la version anglaise de ce document
       en utilisant la commande << man -L C <section> <page_de_man> >>.