IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Web Perl Discussion :

[web] Barre de Progression ASCII


Sujet :

Web Perl

  1. #1
    Candidat au Club
    Inscrit en
    Juin 2003
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 10
    Points : 4
    Points
    4
    Par défaut [web] Barre de Progression ASCII
    Je voudrais savoir comment faire une "barre de progression" en Perl.
    En fait il s'agirait plutot d'un enchainement de caractères , style / - \ | pour simuler une attente.
    j'ai trouvé ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    sub _barre_progression
    {
     
    	my @spin = ('|','/','-','\\');           #initialise les éléments pour l'attente
    	my $i = 0;                               #initialise l'index
     
    	while(1)                                 
    	{
          	  print $spin[$i];                 #aiffche l'élément de la barre
    	        sleep 1;                         #attend un peu
          	  print chr 8;                     #efface le caractère
    	        $i = ($i+1) % scalar @spin;      #incrémente l'index
    	}
    }
    Mais le soucis c'est le While(1).
    L'ideal serait de pouvoir lancer cette routine avant un long traitement, et pouvoir l'arrêter à la fin. Telle qu'elle est programmée, elle va tourner sans arrêt !!
    Je sais qu'il existe une lib appellée twiddle sur CPAN, mais malheureusement je ne peux pas installer de nouvelle lib sur le PC où Perl tourne (pb d'admin et maintenance). Donc tout le code nécessaire sera dans le programme principal.

    Merci d'avance

  2. #2
    Membre expérimenté
    Avatar de nyal
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    622
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2002
    Messages : 622
    Points : 1 428
    Points
    1 428
    Par défaut
    Il te suffit d'inserer ton code. La barre de progression fonctionnera a un moment voulu. Tu ne peux faire deux choses en meme temps dans le meme processus.

    Mais tu peux aussi creer un processus fils qui fera la barre de progression. Ensuite tu enverras un signal kill a ce processus une fois ton traitement dans le pere fini.

    Tu peux faire des barres de progression en gtk (et autres librairies graphiques). Mais utiliser une aussi grosse pour faire une barre de progression X, ce n'est pas terrible.

    S'il n'y a pas d'affichage dans le pere et que tu veux que la barre fonctionne tout le temps. La deuxieme methode est la bonne.

  3. #3
    Candidat au Club
    Inscrit en
    Juin 2003
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    Je n'ai pas du être assez précis. .Les manipulations qui sont longues à effectuer sont des requêtes SNMP avec la lib NET::SNMP. Donc les process n'ont pas vraiment lieu dans le programme principal.

    Si je fais un while(1), les requêtes vont partir en parallèle, et quand elles vont être achevées, ça va toujours tourner ma petite barre, non ?

    En revanche, l'idée d'un process fils est pas mauvaise du tout !! Je vais voir dans cette direction, mais si quelqu'un a d'autres idées à proposer...

  4. #4
    Membre expérimenté
    Avatar de nyal
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    622
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2002
    Messages : 622
    Points : 1 428
    Points
    1 428
    Par défaut
    Voici un code source pour te montrer.:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
     
    $| = 1;
     
    sub _barre_progression
    {
     
        my @spin = ('|','/','-','\\');
        my $i = 0;
     
        $i = ($i+1) % scalar @spin;
        while(1)
        {
            print $spin[$i];
            sleep 1;
            print chr 8;
            $i = ($i+1) % scalar @spin;
        }
    }
     
    print "Downloading ";
    if (!(my $pid_fils = fork())) {
        &_barre_progression;
    } else {
        # mettre les traitements au lieu de while (1)                               
        while (1) {}
        kill 9, $pid_fils;
    }
    Cordialement

  5. #5
    Candidat au Club
    Inscrit en
    Juin 2003
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    ça fait une demi heure que j'essaie de faire marcher cette solution, en vain !!
    Le programme se bloque en prenant toutes les ressources !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    if (!defined(my $pid_fils = fork()))
    	{
    		die "cannot fork: $!";
    	}
    	elsif ($pid_fils)
    	{ 
    		print "DEBUG, on est dans le père\n";
    		... requêtes SNMP...
    		kill 9, $pid_fils;
    	}
    	else
    	{ 
    		print "DEBUG, on est dans le fils\n";
    		&_barre_progression(); 
    	}
    rien ne s'affiche !!

  6. #6
    Candidat au Club
    Inscrit en
    Juin 2003
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    J'ai peut être une autre idée : utiliser les signaux !
    On arme un signal au bon endroit, on lance la procedire du truc qui tourne, et à la fin de l'exécution des requêtes SNMP on envoie un signal.
    Dans la procédure du truc qui tourne, in sort du while(1) dès que le signal est reçu.

    C'esr réalisable ça ?? (dédolé pour l'explication très aproximative, mais je vois à peu près l'algo en C, mais en Perl, je n'ai jamais manipulé les signaux )

  7. #7
    Membre expérimenté
    Avatar de nyal
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    622
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2002
    Messages : 622
    Points : 1 428
    Points
    1 428
    Par défaut
    je ne vois pas le probleme. Cela fonctionne pour moi. (En ne prenant pas 100% du CPU)

    Le programme n'affiche rien du tout ?

  8. #8
    Candidat au Club
    Inscrit en
    Juin 2003
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    Non, ça n'affiche rien du tout.
    ça doit venir de la librairie Net::SNMP qui doit bloquer le système.
    j'essaie quelque chose avec un signal SIGALARM...

  9. #9
    Membre expérimenté
    Avatar de nyal
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    622
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2002
    Messages : 622
    Points : 1 428
    Points
    1 428
    Par défaut
    Voici une autre methode qui est moins bonne je trouve :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
     
    $| = 1;
     
    # fonction barre de progression
     
    sub _barre_progression
    {
        my @spin = ('|','/','-','\\');
        my $i = 0;
     
        $i = ($i+1) % scalar @spin;
        while(1)
        {
            print $spin[$i];
            sleep 1;
            print chr 8;
            $i = ($i+1) % scalar @spin;
            if ($quit_func) {
                return ;
            }
        }
    }
     
    sub kill_progression {
        $quit_func = 1;
    }
     
    our $quit_func = 0;
    $SIG{'USR1'}  = \&_barre_progression;
    # $SIG{'USR2'}  = \&kill_progression;                                           
    kill 'USR1', $$;
    # traitement a la place du while                                                
    while (1) {
     
    }
    $quit_func = 1; # va killer la fonction proression , peut utiliser un signal aussi
    Ca fonctionne tres bien.

  10. #10
    Candidat au Club
    Inscrit en
    Juin 2003
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    C'est bien vers cette méthode que je voulais m'orienter, mais le problème c'est qu'une fois aue _barre_progression est lancé, le while(1) est bloquant et la suite des opérations ne s'effectue pas !!
    ou alors je ne comprends pas le code...

  11. #11
    Candidat au Club
    Inscrit en
    Juin 2003
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    J'ai le message d'erreur suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Unrecognized signal name "USR1" at iec.pl line 285.
    L'erreur est toujours là en utilisant SIGUSR1
    Il y a des déclarations particumières à faire au début du programme ?

  12. #12
    Membre expérimenté
    Avatar de nyal
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    622
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2002
    Messages : 622
    Points : 1 428
    Points
    1 428
    Par défaut
    Citation Envoyé par Red Bull
    J'ai le message d'erreur suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Unrecognized signal name "USR1" at iec.pl line 285.
    L'erreur est toujours là en utilisant SIGUSR1
    Il y a des déclarations particumières à faire au début du programme ?
    Tu es sous quel systeme d'exploitation ?

    Tu peux tres bien utiliser le signal ALARM :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $SIG{ALRM} = \&_barre_progression;
    kill 'ALRM', $$;

  13. #13
    Candidat au Club
    Inscrit en
    Juin 2003
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    C'est bon, problème résolu avec SIGALRM !!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    #Init de la barre de progression
    #@spin = ('|','/','-','\\');                                       #plusieurs modèles au choix !
    #@spin = ('> ','-> ','-->','---> ','--> ','-> '); 
    @spin = ('o---','-o--','--o-','---o','--o-','-o--'); 
    $index_barre = 0; 
    $SIG{'ALRM'} = \&_barre_progression;
    ...
    #lance la barre de progression
    &_lance_barre();
    .. #données à traiter...
    &_arrete_barre();	
    ..
     
    # -----------------------------------------------------------------
    # Routines d'animation de la barre de progression 
    # -----------------------------------------------------------------
    sub _lance_barre
    {
    	$quitte_barre = 0;
    	$index_barre = 0; 
    	alarm(1);
    }
     
    sub _arrete_barre
    {
    	$quitte_barre = 1;
    }
     
    sub _barre_progression 
    { 
      	$index_barre = ($index_barre+1) % scalar @spin; 
    	if (!$quitte_barre) 
    	{ 	
    		print $spin[$index_barre];
    		alarm(1); 
    		for (my $i=0;$i<length($spin[$index_barre]);$i++)
    		{
     			print chr 8; 
    		}
    	}
        	if ($quitte_barre) 
    	{ 
    		alarm(0);
    	}
    }
    En tout cas, merci BEAUCOUP nyal pour ton aide et ta disponibilté !!

    Si quelqu'un a des idées de design intéressantes pour faire une barre de progression avec des caractères ASCII, n'hésitez pas !!

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2002
    Messages : 68
    Points : 73
    Points
    73
    Par défaut
    Génial, c'est exactement ce que je cherchais à faire pour faire patienter durant le traitement !!

    Merci beaucoup
    Ce n’est pas parce que les choses sont difficiles que nous n’osons pas ; c’est parce que nous n’osons pas qu’elles sont difficiles.
    Sénèque

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Barre de progression JProgressBar
    Par sixkiller dans le forum Composants
    Réponses: 7
    Dernier message: 08/12/2004, 11h33
  2. Indy FTP (idFTP) faire une barre de progress de transfert
    Par Harry dans le forum Web & réseau
    Réponses: 4
    Dernier message: 09/07/2004, 13h15
  3. [VB.NET] Pb avec le bouton Annuler d'1 barre de progression
    Par dada1982 dans le forum Windows Forms
    Réponses: 3
    Dernier message: 30/06/2004, 09h56
  4. Réponses: 12
    Dernier message: 27/05/2004, 00h13
  5. [DEBUTANT] Barre de progression
    Par pupupu dans le forum MFC
    Réponses: 4
    Dernier message: 18/01/2004, 16h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo