Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
716 connectés 

  FORUM HardWare.fr
  Programmation
  Perl

  Plantage appli perl/tk lors d'une boucle ?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Plantage appli perl/tk lors d'une boucle ?

n°830638
sygn
Posté le 24-08-2004 à 11:27:51  profilanswer
 

bonjour,
 
je fait une appli en perl:tk sous windows.
Dans cette appli, j'ai une boucle qui attend la creation d'un fichier texte. Cependant, lors de cette boucle, mon appli tk plante (je n'ai pas la main).
je debute en perl et je ne vois pas trop comment eviter ce probleme.
merci

Code :
  1. do{
  2.       $texte="Attente";
  3.       $message -> configure ( -text => $texte ) ;
  4. }
  5. until( not -z "result.txt" ) ;


 

mood
Publicité
Posté le 24-08-2004 à 11:27:51  profilanswer
 

n°830839
pospos
Posté le 24-08-2004 à 14:18:37  profilanswer
 

si tu boucle tu ne laisse plus Tk gerer ses evenements (rafraichissement, etc...)
 
bon deja dans ta boucle tu n'a pas à remettre le texte en permanance, il te suffit de trouner dans le vide:

Code :
  1. $message->configure(-text => "Attente" );
  2. 1 while ( -z "result.txt" );
  3. $message->configure(-text => "Ok" );


 
ensuite si tu faix ca tu va utiliser 100% de ton CPU à tourner comme un fou pour pas grand chose. Donc tu peux deja ajouter des petites pauses:

Code :
  1. $message->configure(-text => "Attente" );
  2. while ( -z "result.txt" ) {
  3. select(undef,undef,undef, 0.01);
  4. }
  5. $message->configure(-text => "Ok" );


 
le select(undef,undef,undef, 0.01) va simplement faire une pause de 0.01 seconde
 
ensuite il faudrait que tu permete à Tk de gerer ses evenements pendant que tu boucle:
 

Code :
  1. # $mw = fenetre principale
  2. $message->configure(-text => "Attente" );
  3. while ( -z "result.txt" ) {
  4. select(undef,undef,undef, 0.01);
  5. $mw->update;
  6. }
  7. $message->configure(-text => "Ok" );


 
et ensuite, le fin du fin serais de ne pas avoir de boucle mais de demander à Tk de gerer cette attente lui meme, avec ses timer:
 

Code :
  1. # $mw = fenetre principale
  2. $message->configure(-text => "Attente" );
  3. my $timer;
  4. # toutes les 100ms, ca doit deja largement suffire
  5. $timer = $mw->repeat(100, sub{
  6. if (not -z "result.txt" ) { # ou if -s...
  7.  $timer->cancel; # on cancel le timer pour ne plus qu'il tourne
  8.  $message->configure(-text => "Ok" );
  9.  ...
  10. }
  11. });

n°830853
pospos
Posté le 24-08-2004 à 14:30:17  profilanswer
 

mais bon dans tous les cas cette solution n'est pas nonplus optimale car la commande -z (stat en fait) est bloquante: si le fichier se trouve sur un support tres lent (genre disquette) alors ca risque de bloquer qq instant à chaque fois (mais rien à voir avec ton probleme actuel, je te rassure). Dans ce cas il faudrait utiliser la fonction filevent de Tk, mais elle est assez foireuse (surtout sous Windows). Le problème c'est que les operations sur le systeme de fichiers sont toujours synchrones.
Si tu es sous Linux tu peux toujours utiliser la fonction aio_stat de Linux::AIO...
Enfin bon je pense pas que ce soit vraiment ce dont tu a besoin nonplus!
 
Enfin pour le fun:
 

Code :
  1. use Linux::AIO;
  2. $message->configure(-text => "Attente" );
  3. wait_size("result.txt", \&fichier_ok);
  4. sub wait_size {
  5. my ($fichier, $cb) = @_;
  6. aio_stat($fichier, sub{
  7.  if (-z _) {
  8.   $mw->after(100, [\&wait_size, $fichier, $cb]);
  9.  } else {
  10.   $cb->($fichier);
  11.  }
  12. });
  13. }
  14. sub fichier_ok {
  15. my $fichier = shift;
  16. $message->configure(-text => "Ok" );
  17. ...
  18. }


Message édité par pospos le 24-08-2004 à 14:31:52
n°830895
sygn
Posté le 24-08-2004 à 15:48:40  profilanswer
 

j'suis en admiration devant tant d'attention....:love:
 
j'ai essayé tes solutions (sauf la dernère je suis sur windows).
la 3ème :

Code :
  1. # $mw = fenetre principale
  2.   $message->configure(-text => "Attente" );
  3.   while ( -z "result.txt" ) {
  4.      select(undef,undef,undef, 0.01);
  5.      $mw->update;
  6.   }
  7.   $message->configure(-text => "Ok" );


est la meilleure, la dernière avec le repeat ne marche pas?? :??:  
c pas super fluide mais c correct
merci

n°830939
pospos
Posté le 24-08-2004 à 16:42:35  profilanswer
 

bizarre que la version avec le timer ne marche pas...
j'ai pas testé mais dans le principe ca doit fonctionner (et c'est la meilleur solution)
 
sinon pour la solution avec le select, si tu veux un truc plus fluide met 0.001 à la place de 0.01, mais ca risque de mettre ton system de fichier sur els rotules (c'est d'ailleurs sans doute deja pour ca que ca rame, donc ca changera rien)
 
Donc le mieux c'est de faire moins de tests sur le fichier, par exemple seulement une fois sur 100, tout en bouclant plus souvent:
 

Code :
  1. # $mw = fenetre principale 
  2. $message->configure(-text => "Attente" ); 
  3. my $i=0;
  4. for(;;) {
  5. unless (++$i%100) {
  6.  # test le fichier toutes les 100*0.001 = 0.1 secondes
  7.  last unless -z "result.txt";
  8. }
  9. $mw->update;
  10. select(undef,undef,undef, 0.001);
  11. $message->configure(-text => "Ok" );


 
si tu peux meme tester le fichier encore moins souvent (genre ++$i%500 pour 0.5s) ca sera encore mieux
 
mais bon, ca vaut pas un vrai timer Tk

n°831019
sygn
Posté le 24-08-2004 à 17:37:02  profilanswer
 

tu as raison, le timer marche très bien.
en fait l'erreur vient de moi, je me suis trompé de problème. :pt1cable:  
je croyais que c'etait l'attente d'un fichier qui buggait mon appli, en fait non...
j'execute juste avant l'attente de ce fichier un exe qui prend beaucoup de temps.je croyais que cette execution etait indépendante de mon appli perl/tk.
donc le pb existe toujours... :(
je remet donc le pgr avec l'executable.  

Code :
  1. print `pgr.exe $a $b $c >result.txt `  ;
  2.           while (-z "result.txt" ) {
  3.                        select(undef,undef,undef, 1);
  4.                        $fenetre->update;
  5.                 };


l'exe prg.exe dure de 20s a 5min et c bien lui qui fait planter l'appli.
si tu vois une solution ca m'interesse. :sarcastic:  

n°831044
pospos
Posté le 24-08-2004 à 17:48:20  profilanswer
 

ha ouai, un programme externe c'est plus chiant...
tu peux utiliser la commande system(1,...)
 
c'est une version non documenté de 'system' (et qui marche peut etre que sous activePerl, mais comme j'imagine que c'est ce que tu utilise tout va bien)
 
en fait c'est un 'system' non bloquant: il lance un processus independant (utilisant la meme console)
 
donc tu fais simplement:
system(1, "pgr.exe $a $b $c >result.txt" );
while...
 
mais pour le select met tout de meme autre chose que 1s, sinon il ne rafraichira la fenetre Tk que une fois par seconde. pour l'instant tu ne le vois pas car l'execution de l'exe bloque et le fichier result.txt est remplie kand ca ne bloque plus, mais avec system(1,...) il faudra effectivement que tu attende que le fichier se remplisse (avec le timer)

n°831749
sygn
Posté le 25-08-2004 à 11:57:37  profilanswer
 

salut,
c bon c'etait bien ca.
je te remercie
a+


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Perl

  Plantage appli perl/tk lors d'une boucle ?

 

Sujets relatifs
Partager des données entre plusieurs appli-webconstruction d'un boucle
Problème avec un boucle For Each et une fonction recursive[VC++] Changer le curseur au lancement d'une appli (busy)
[Perl] Programmation XSfaire une barre de progression pour chargement appli[Applet]
[C] plantage a la liberation de la memoiredetecter la fin dune appli win32
boucle avec attributs[Perl] est-il possible d'exécuter une application Perl sur un hébergeu
Plus de sujets relatifs à : Plantage appli perl/tk lors d'une boucle ?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR