GNT sans publicité, site mobile, fonctionnalitées exclusives...

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
Lire les 6 réponses

Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Nicolas George
Le #515790
"Eric Bart" wrote in message
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 ?


De quel genre d'événement s'agit-il ? Disponibilité de données sur un fd ?
Action d'un autre thread ?

Gilles Berger Sabbatel
Le #515788
On Thu, 21 Oct 2004 21:40:42 +0200, Eric Bart wrote:

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 ?


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

J'ai essayé nanosleep sans succès et je ne connais pas les signaux...


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

Eric Bart
Le #515787
De quel genre d'événement s'agit-il ? Disponibilité de données sur un fd ?
Action d'un autre thread ?


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 ?

Stephane Chazelas
Le #515786
2004-10-22, 10:12(+02), Gilles Berger Sabbatel:
[...]
- être prévenu du changement de la valeur par un signal, et attendre par
select(2), poll(2), ou simplement pause(2).
[...]


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

Erwann ABALEA
Le #515785
On Fri, 22 Oct 2004, Eric Bart wrote:

De quel genre d'événement s'agit-il ? Disponibilité de données sur un fd ?
Action d'un autre thread ?


C'est une autre thread qui remplit une variable partagée.


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.

usleep résout mon problème. Est-ce la bonne méthode ?


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 -+-


Publicité
Suivre les réponses
Poster une réponse
Anonyme