Provided by:
manpages-fr_3.32d0.2p4-1_all 
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> >>.