Je cherche à écrire un producteur de contenu dans un fichier FIFO:
mkfifo decision
#!/usr/bin/perl -Tw
use FileHandle;
my $fh = new FileHandle("decision", "w");
sub value {
print "Evaluation !\n";
return 5;
}
while (1) {
$fh->print(&value() . "\n\004");
}
Lorsque je lance le processus, et que je fais 'cat decision', je m'attends à
ce qu'une seule ligne sorte et que 'cat' termine sur EOF (\004 mais c'est
peut-être une erreur ?).
Actuellement ce code boucle à l'infini, 'cat' ne se termine jamais.
Une solution serait d'ouvrir et fermer le fichier à chaque ouverture par un
consommateur mais je me pose des questions de performance et si possible
j'aimerai conserver le descripteur de fichier ouvert.
Savez-vous ce qui ne fonctionne pas dans mon code ? Comment sortir un 'EOF'
sur le FIFO sans effectivement fermer le fichier ?
Merci d'avance pour votre aide
--
Yves Martin
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Stephane Chazelas
2005-01-13, 10:46(+01), Yves Martin: [...]
while (1) { $fh->print(&value() . "n 04"); }
Lorsque je lance le processus, et que je fais 'cat decision', je m'attends à ce qu'une seule ligne sorte et que 'cat' termine sur EOF ( 04 mais c'est peut-être une erreur ?).
Oui, 4 n'est le charactere d'eof que pour un terminal (a moins qu'on ne le change par un stty eof 'autre-character').
Il faut fermer le handle coté perl pour que cat voie un eof.
-- Stephane
2005-01-13, 10:46(+01), Yves Martin:
[...]
while (1) {
$fh->print(&value() . "n 04");
}
Lorsque je lance le processus, et que je fais 'cat decision', je m'attends à
ce qu'une seule ligne sorte et que 'cat' termine sur EOF ( 04 mais c'est
peut-être une erreur ?).
Oui, 4 n'est le charactere d'eof que pour un terminal (a moins
qu'on ne le change par un stty eof 'autre-character').
Il faut fermer le handle coté perl pour que cat voie un eof.
Lorsque je lance le processus, et que je fais 'cat decision', je m'attends à ce qu'une seule ligne sorte et que 'cat' termine sur EOF ( 04 mais c'est peut-être une erreur ?).
Oui, 4 n'est le charactere d'eof que pour un terminal (a moins qu'on ne le change par un stty eof 'autre-character').
Il faut fermer le handle coté perl pour que cat voie un eof.
-- Stephane
Yves Martin
Stephane Chazelas writes:
2005-01-13, 10:46(+01), Yves Martin: [...]
while (1) { $fh->print(&value() . "n 04"); }
Lorsque je lance le processus, et que je fais 'cat decision', je m'attends à ce qu'une seule ligne sorte et que 'cat' termine sur EOF ( 04 mais c'est peut-être une erreur ?).
Oui, 4 n'est le charactere d'eof que pour un terminal (a moins qu'on ne le change par un stty eof 'autre-character').
Il faut fermer le handle coté perl pour que cat voie un eof.
C'est ce que j'ai fait mais ce n'est visiblement pas suffisant.
#!/usr/bin/perl -Tw
use FileHandle;
my $fh = new FileHandle();
while (1) { $fh->open("decision", "w"); $fh->print("5n"); $fh->close(); ## sleep(1); }
Maintenant cela donne un nombre de lignes aléatoires dans 'cat' !!!
yma ~/perl> cat decision | wc 286 286 572 yma ~/perl> cat decision | wc 461 461 922 yma ~/perl> cat decision | wc 127 127 254 yma ~/perl> cat decision | wc 143 143 286
En rajoutant 'sleep(1)', le résultat mais juste mais ce n'est pas la réactivité à laquelle je m'attendais... Est-ce que l'on peut mieux faire ? Et comment ?
Je pense à: - un sleep qui serait de qq microsecondes ? - un flush avant le close ? - forcer le changement de contexte après le close ?
Lorsque je lance le processus, et que je fais 'cat decision', je m'attends
à ce qu'une seule ligne sorte et que 'cat' termine sur EOF ( 04 mais c'est
peut-être une erreur ?).
Oui, 4 n'est le charactere d'eof que pour un terminal (a moins
qu'on ne le change par un stty eof 'autre-character').
Il faut fermer le handle coté perl pour que cat voie un eof.
C'est ce que j'ai fait mais ce n'est visiblement pas suffisant.
#!/usr/bin/perl -Tw
use FileHandle;
my $fh = new FileHandle();
while (1) {
$fh->open("decision", "w");
$fh->print("5n");
$fh->close();
## sleep(1);
}
Maintenant cela donne un nombre de lignes aléatoires dans 'cat' !!!
yma ~/perl> cat decision | wc
286 286 572
yma ~/perl> cat decision | wc
461 461 922
yma ~/perl> cat decision | wc
127 127 254
yma ~/perl> cat decision | wc
143 143 286
En rajoutant 'sleep(1)', le résultat mais juste mais ce n'est pas la
réactivité à laquelle je m'attendais... Est-ce que l'on peut mieux faire ? Et
comment ?
Je pense à:
- un sleep qui serait de qq microsecondes ?
- un flush avant le close ?
- forcer le changement de contexte après le close ?
Lorsque je lance le processus, et que je fais 'cat decision', je m'attends à ce qu'une seule ligne sorte et que 'cat' termine sur EOF ( 04 mais c'est peut-être une erreur ?).
Oui, 4 n'est le charactere d'eof que pour un terminal (a moins qu'on ne le change par un stty eof 'autre-character').
Il faut fermer le handle coté perl pour que cat voie un eof.
C'est ce que j'ai fait mais ce n'est visiblement pas suffisant.
#!/usr/bin/perl -Tw
use FileHandle;
my $fh = new FileHandle();
while (1) { $fh->open("decision", "w"); $fh->print("5n"); $fh->close(); ## sleep(1); }
Maintenant cela donne un nombre de lignes aléatoires dans 'cat' !!!
yma ~/perl> cat decision | wc 286 286 572 yma ~/perl> cat decision | wc 461 461 922 yma ~/perl> cat decision | wc 127 127 254 yma ~/perl> cat decision | wc 143 143 286
En rajoutant 'sleep(1)', le résultat mais juste mais ce n'est pas la réactivité à laquelle je m'attendais... Est-ce que l'on peut mieux faire ? Et comment ?
Je pense à: - un sleep qui serait de qq microsecondes ? - un flush avant le close ? - forcer le changement de contexte après le close ?
Merci pour votre aide -- Yves Martin
Stephane Chazelas
2005-01-13, 11:47(+01), Yves Martin: [...]
#!/usr/bin/perl -Tw
use FileHandle;
my $fh = new FileHandle();
while (1) { $fh->open("decision", "w"); $fh->print("5n"); $fh->close(); ## sleep(1); }
Maintenant cela donne un nombre de lignes aléatoires dans 'cat' !!!
yma ~/perl> cat decision | wc 286 286 572
Le probleme survient quand perl a le temps de faire le print le close et le 2e open entre le moment ou cat fait son open et son read.
Il faudrait que perl attende que cat ait eu son eof avant de reouvrir le fichier. Une alternative est de recreer un nouveau pipe.
- est-on sûr de ne "rien" perdre ? Mon fifo doit fournir une et une seule ligne à un autre processus (bien sur 'cat' est simplement utilisé pour mes tests)
- est-ce que la gestion des 'inode' sur le filesystem ne va pas exploser ?
- ne serait-il pas mieux d'utiliser un autre mécanisme qu'un fifo pour assurer la qualité de communication ? (je pense à une socket Unix ou autres IPC)
- est-on sûr de ne "rien" perdre ?
Mon fifo doit fournir une et une seule ligne à un autre processus (bien sur
'cat' est simplement utilisé pour mes tests)
- est-ce que la gestion des 'inode' sur le filesystem ne va pas exploser ?
- ne serait-il pas mieux d'utiliser un autre mécanisme qu'un fifo pour assurer
la qualité de communication ? (je pense à une socket Unix ou autres IPC)
- est-on sûr de ne "rien" perdre ? Mon fifo doit fournir une et une seule ligne à un autre processus (bien sur 'cat' est simplement utilisé pour mes tests)
- est-ce que la gestion des 'inode' sur le filesystem ne va pas exploser ?
- ne serait-il pas mieux d'utiliser un autre mécanisme qu'un fifo pour assurer la qualité de communication ? (je pense à une socket Unix ou autres IPC)
Merci pour ton aide précieuse -- Yves Martin
Stephane Chazelas
2005-01-13, 14:14(+01), Yves Martin:
Stephane Chazelas writes:
Le probleme survient quand perl a le temps de faire le print le close et le 2e open entre le moment ou cat fait son open et son read.
Etrange. Je n'ai pas ce genre de problème avec un shell script si je me souviens bien. Mais il est vrai qu'un processus est forké à chaque demande.
while( true ); do; fortune > fifo; done
Oui, avec le fork et la lenteur generale des shell, ca limite la probabilité que ca arrive.
Oui a priori, a moins que perl ou cat plantent au milieu de leur ecriture/lecture.
Mon fifo doit fournir une et une seule ligne à un autre processus (bien sur 'cat' est simplement utilisé pour mes tests)
Alors pas la peine de fermer le pipe, lit juste une ligne a la fois (en lisant un caractere a la fois si plusieurs processus doivent lire sur le fifo).
Un autre solution est de faire repondre le deuxieme processus (cat) pour une meilleur synchronisation.
- est-ce que la gestion des 'inode' sur le filesystem ne va pas exploser ?
Non, pourquoi.
- ne serait-il pas mieux d'utiliser un autre mécanisme qu'un fifo pour assurer la qualité de communication ? (je pense à une socket Unix ou autres IPC)
Oui, les sockets sont plus flexible, surtout s'il y a plus de 2 process.
Oui a priori, a moins que perl ou cat plantent au milieu de leur
ecriture/lecture.
Mon fifo doit fournir une et une seule ligne à un autre processus (bien sur
'cat' est simplement utilisé pour mes tests)
Alors pas la peine de fermer le pipe, lit juste une ligne a la
fois (en lisant un caractere a la fois si plusieurs processus
doivent lire sur le fifo).
Un autre solution est de faire repondre le deuxieme processus
(cat) pour une meilleur synchronisation.
- est-ce que la gestion des 'inode' sur le filesystem ne va pas exploser ?
Non, pourquoi.
- ne serait-il pas mieux d'utiliser un autre mécanisme qu'un fifo pour assurer
la qualité de communication ? (je pense à une socket Unix ou autres IPC)
Oui, les sockets sont plus flexible, surtout s'il y a plus de 2
process.
Oui a priori, a moins que perl ou cat plantent au milieu de leur ecriture/lecture.
Mon fifo doit fournir une et une seule ligne à un autre processus (bien sur 'cat' est simplement utilisé pour mes tests)
Alors pas la peine de fermer le pipe, lit juste une ligne a la fois (en lisant un caractere a la fois si plusieurs processus doivent lire sur le fifo).
Un autre solution est de faire repondre le deuxieme processus (cat) pour une meilleur synchronisation.
- est-ce que la gestion des 'inode' sur le filesystem ne va pas exploser ?
Non, pourquoi.
- ne serait-il pas mieux d'utiliser un autre mécanisme qu'un fifo pour assurer la qualité de communication ? (je pense à une socket Unix ou autres IPC)
Oui, les sockets sont plus flexible, surtout s'il y a plus de 2 process.
-- Stephane
Yves Martin
Stephane Chazelas writes:
Mon fifo doit fournir une et une seule ligne à un autre processus (bien sur 'cat' est simplement utilisé pour mes tests)
Alors pas la peine de fermer le pipe, lit juste une ligne a la fois (en lisant un caractere a la fois si plusieurs processus doivent lire sur le fifo).
Effectivement, je n'avais pas pensé à cela.
- est-ce que la gestion des 'inode' sur le filesystem ne va pas exploser ?
Non, pourquoi.
Parce que faire des unlink / mkfifo en permanence ne me semble pas naturel.
- ne serait-il pas mieux d'utiliser un autre mécanisme qu'un fifo pour assurer la qualité de communication ? (je pense à une socket Unix ou autres IPC)
Oui, les sockets sont plus flexible, surtout s'il y a plus de 2 process.
Comme c'est un script PHP (donc éventuellement plusieurs processus) qui vont lire le résultat de mon évaluation en Perl, il me faut une solution robuste.
Donc j'ai tout implémenté sur une socket TCP avec un basic protocol d'interrogation.
Finallement les FIFO c'est facile et pas cher mais il ne faut pas trop leur en demander.
Mon fifo doit fournir une et une seule ligne à un autre processus (bien
sur 'cat' est simplement utilisé pour mes tests)
Alors pas la peine de fermer le pipe, lit juste une ligne a la
fois (en lisant un caractere a la fois si plusieurs processus
doivent lire sur le fifo).
Effectivement, je n'avais pas pensé à cela.
- est-ce que la gestion des 'inode' sur le filesystem ne va pas exploser ?
Non, pourquoi.
Parce que faire des unlink / mkfifo en permanence ne me semble pas naturel.
- ne serait-il pas mieux d'utiliser un autre mécanisme qu'un fifo pour
assurer la qualité de communication ? (je pense à une socket Unix ou autres
IPC)
Oui, les sockets sont plus flexible, surtout s'il y a plus de 2
process.
Comme c'est un script PHP (donc éventuellement plusieurs processus) qui vont
lire le résultat de mon évaluation en Perl, il me faut une solution robuste.
Donc j'ai tout implémenté sur une socket TCP avec un basic protocol
d'interrogation.
Finallement les FIFO c'est facile et pas cher mais il ne faut pas trop leur en
demander.
Mon fifo doit fournir une et une seule ligne à un autre processus (bien sur 'cat' est simplement utilisé pour mes tests)
Alors pas la peine de fermer le pipe, lit juste une ligne a la fois (en lisant un caractere a la fois si plusieurs processus doivent lire sur le fifo).
Effectivement, je n'avais pas pensé à cela.
- est-ce que la gestion des 'inode' sur le filesystem ne va pas exploser ?
Non, pourquoi.
Parce que faire des unlink / mkfifo en permanence ne me semble pas naturel.
- ne serait-il pas mieux d'utiliser un autre mécanisme qu'un fifo pour assurer la qualité de communication ? (je pense à une socket Unix ou autres IPC)
Oui, les sockets sont plus flexible, surtout s'il y a plus de 2 process.
Comme c'est un script PHP (donc éventuellement plusieurs processus) qui vont lire le résultat de mon évaluation en Perl, il me faut une solution robuste.
Donc j'ai tout implémenté sur une socket TCP avec un basic protocol d'interrogation.
Finallement les FIFO c'est facile et pas cher mais il ne faut pas trop leur en demander.