bizarreries avec sleep et while (1)
Le
gvdmoort
Bonjour à tous,
J'exécute ceci
#!/usr/bin/perl
use strict;
while (1) {
print ". ";
# sleep 1;
}
et comme attendu, mon terminal se couvre de petits points.
J'interrompt avec Ctl-c
Je décommente la ligne avec le sleep, j'exécute le script et rien
ne se passe, le curseur reste immobile.
Je fais un Ctl-c, j'ajoute un à la chaîne
print ". ";
et le résultat est bien un point par ligne à intervalle d'une seconde.
Je ne comprends absolument pas, qu'est-ce qui explique ça ? (Inutile
de préciser que la chose se déroulait avec un script plus élaboré e=
t
que j'ai passé un temps fou à en trouver la raison)
Pour aller plus loin, qu'est-ce qui pourrait remplacer cette
construction rudimentaire pour lancer une fonction à intervalle
régulier ?
while (1) {
&faire_quelque_chose
sleep 15;
}
Comme la fonction s'exécute en un temps variable, l'intervalle
s'allonge et l'exécution se décale dans le temps; comme elle collecte
des données que je souhaite intégrer d
J'exécute ceci
#!/usr/bin/perl
use strict;
while (1) {
print ". ";
# sleep 1;
}
et comme attendu, mon terminal se couvre de petits points.
J'interrompt avec Ctl-c
Je décommente la ligne avec le sleep, j'exécute le script et rien
ne se passe, le curseur reste immobile.
Je fais un Ctl-c, j'ajoute un à la chaîne
print ". ";
et le résultat est bien un point par ligne à intervalle d'une seconde.
Je ne comprends absolument pas, qu'est-ce qui explique ça ? (Inutile
de préciser que la chose se déroulait avec un script plus élaboré e=
t
que j'ai passé un temps fou à en trouver la raison)
Pour aller plus loin, qu'est-ce qui pourrait remplacer cette
construction rudimentaire pour lancer une fonction à intervalle
régulier ?
while (1) {
&faire_quelque_chose
sleep 15;
}
Comme la fonction s'exécute en un temps variable, l'intervalle
s'allonge et l'exécution se décale dans le temps; comme elle collecte
des données que je souhaite intégrer d

Poser une question


Comme la fonction s'exécute en un temps variable, l'intervalle
s'allonge d'autant et l'exécution se décale dans le temps; comme elle
collecte
des données que je souhaite intégrer dans un graphe, j'aimerais que
l'intervalle reste constant.
Merci d'avance,
Gauthier
#!/usr/bin/perl
use strict;
while (1) {
local $|=1;
print ". ";
sleep 1;
}
perldoc perlvar pour la signification de $|
Dans ce cas, il faut procéder autrement en programmant un signal
(grossièrement) périodique :
#!/usr/bin/perl
use strict;
use warnings;
local $SIG{ALRM} = sub { local $|=1; print '. '; alarm(1); };
alarm(1);
while (1) { # remplace cette boucle par ton traitement.
}
Attention : l'utilisation de cette méthode empêche d'utiliser sleep();
dans le script.
gvdmoort
La sortie standard est bufferisée (ou tamponnée pour parler français)
par ligne si elle est reliée à un terminal et par bloc sinon. Dans le
cas d'un terminal, tout ce qu'on y écrit n'est réellement envoyé que
lorsqu'on y écrit un passage à la ligne ou lorsque le tampon est plein.
Pour répondre au souci ci-dessus, soit on fait appel à flush soi-même
pour forcer le vidage du tampon :
use IO::Handle;
while(1) {
print ".";
STDOUT->flush;
sleep 1;
}
soit on utilise 'autoflush' sur STDOUT pour que le vidage ait lieu à
chaque écriture :
use IO::Handle;
autoflush STDOUT 1;
while(1) {
print ".";
sleep 1;
}
--
Paul Gaborit - Perl en français -