OVH Cloud OVH Cloud

comment attendre dans une boucle en C sous linux ?

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

6 réponses

Avatar
Nicolas George
"Eric Bart" wrote in message <417810d1$0$279$:
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 ?

Avatar
Gilles Berger Sabbatel
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...

Avatar
Eric Bart
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 ?

Avatar
Stephane Chazelas
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

Avatar
Erwann ABALEA
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 - RSA PGP Key ID: 0x2D0EABD5
-----
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 -+-


Avatar
Eric Bart
merci à tous

"Erwann ABALEA" wrote in message news:
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 - RSA PGP Key ID: 0x2D0EABD5
-----
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 -+-