comment attendre dans une boucle en C sous linux ?
Le
Eric Bart
Bonjour,
J'aurais aimé pouvoir attendre un évènement dans une boucle.
Le pourcentage d'utilisation du CPU grimpe en flèche. Est-ce
d'attendre en testant la valeur d'une variable sans monopoliser
le CPU ?
J'ai essayé nanosleep sans succès et je ne connais pas les signaux
Merci
J'aurais aimé pouvoir attendre un évènement dans une boucle.
Le pourcentage d'utilisation du CPU grimpe en flèche. Est-ce
d'attendre en testant la valeur d'une variable sans monopoliser
le CPU ?
J'ai essayé nanosleep sans succès et je ne connais pas les signaux
Merci

Poser une question


De quel genre d'événement s'agit-il ? Disponibilité de données sur un fd ?
Action d'un autre thread ?
Attendre en testant la valeur d'une variable, cela s'appelle de l'attente
active, et cela fait forcément 100% d'utilisation du CPU...
2 solutions :
- être prévenu du changement de la valeur par un signal, et attendre par
select(2), poll(2), ou simplement pause(2).
- introduire une temporisation entre chaque test (ce que vous avez essayé
de faire avec nanosleep), sachant que l'unité de temps est en général
la milliseconde sur les noyaux récents. L'inconvénient est qu'une
temporisation trop longue peut pénaliser votre appli, et si elle est
trop courte, ce sont les perfs de votre machine qui sont pénalisées.
En fait, ce genre de solution est rarement très élégante...
Voir aussi sleep et usleep, plus faciles à utiliser. Mais il vous faudra
bien apprendre à utiliser les signaux, et on ne peut quand même pas vous
donner des cours de programmation par Usenet! RTFM, donc...
C'est une autre thread qui remplit une variable partagée.
Voilà comment j'attends :
while(!variable) {
struct timespec tRequest;
tRequest.tv_nsec= 100000000;
nanosleep(&tRequest,NULL);
}
Sous Mandrake 10.0/2.6 nanosleep utilise trop de resource CPU.
En revanche j'y arrive en utilisant
soit : sleep(1);
soit : usleep(10000);
usleep résout mon problème. Est-ce la bonne méthode ?
[...]
C'est souvent ce que font sleep/usleep internalement:
D'un truss sous Solaris:
-> libc:sleep(0x1, 0x0, 0x0, 0x0)
alarm(0) = 0
sigaction(SIGALRM, 0xFFBEF860, 0xFFBEF910) = 0
sigfillset(0xFF3428D0) = 0
sigprocmask(SIG_BLOCK, 0xFFBEF900, 0xFFBEF8F0) = 0
alarm(1) = 0
Received signal #14, SIGALRM, in sigsuspend() [caught]
sigsuspend(0xFFBEF8E0) Err#4 EINTR
setcontext(0xFFBEF5C8)
alarm(0) = 0
sigprocmask(SIG_UNBLOCK, 0xFFBEF900, 0x00000000) = 0
sigaction(SIGALRM, 0xFFBEF860, 0x00000000) = 0
<- libc:sleep() = 0
-> libc:usleep(0xa, 0x0, 0x0, 0x0)
-> libc:_usleep(0xa, 0x0, 0x0, 0x0)
alarm(0) = 0
setitimer(ITIMER_REAL, 0xFFBEF940, 0xFFBEF930) = 0
sigaction(SIGALRM, 0xFFBEF840, 0xFFBEF8F0) = 0
sigfillset(0xFF3428D0) = 0
sigprocmask(SIG_BLOCK, 0xFFBEF8E0, 0xFFBEF8D0) = 0
setitimer(ITIMER_REAL, 0xFFBEF940, 0x00000000) = 0
Received signal #14, SIGALRM, in sigsuspend() [caught]
sigsuspend(0xFFBEF8C0) Err#4 EINTR
setcontext(0xFFBEF5A8)
sigaction(SIGALRM, 0xFFBEF840, 0x00000000) = 0
sigprocmask(SIG_UNBLOCK, 0xFFBEF8E0, 0x00000000) = 0
setitimer(ITIMER_REAL, 0xFFBEF930, 0x00000000) = 0
<- libc:usleep() = 0
--
Stephane
Ah, ben alors il ne te reste plus qu'à 'man pthread_cond_wait' et 'man
pthread_cond_signal'. C'est pile poil ce qu'il te faut.
Bah non. ;)
--
Erwann ABALEA -----
J'ai reçu un mail parlant d'un petit garçon malade. Je l'ai transféré à
tous ceux que je connaissais. On me dit que c'est un attrape couillons.
Est-ce vrai? Suis-je vraiment aussi con que le prétend ma femme?
-+-C in GNU - Le plus dur dans le mariage, c'est d'en sortir vivant -+-