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

Langage Perl Discussion :

[PERL] Problème en essayant de comprendre fork et pipe


Sujet :

Langage Perl

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    801
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 801
    Points : 314
    Points
    314
    Par défaut [PERL] Problème en essayant de comprendre fork et pipe
    Bonjour à tous,

    Voià, j'essaie de comprendre fork et pipe pour lancer plusieurs processus (fork) et communiquer en eux (pipe) mais je suis long à la détente et j'ai du mal.
    J'ai réaliser un petit script qui calcul des codes héxadécimaux sur 6 caractères. Je veux tester la validité de mon script en lançant 100000 fois la fonctions par exemple.

    Le script qui suit fait deux choses (mais très mal puisque ça marche pas ) ;

    - Boucles qui calcul les codes
    - Insertion des codes dans un tableau
    - Vérification des doublons (s'il y a des codes identiques)

    En parallèle, un processus (le père normalement), lit à intervalle régulier (1 seconde), les données qui sont écrites par le fils sur un pipe et affiche sur la sortie standard ce qu'il lit sur le pipe.

    Voici le script:
    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
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
     
    #!c:\perl\bin\perl.exe
    use IO::Handle ;
     
    if($ARGV[0] eq '')
    {
        print "Il faut rentrer un nombre de tentatives";
    }
    else
    {
          $tentative=$ARGV[0];
          pipe ( LIRE , ECRIRE ) ;
          ECRIRE -> autoflush ( 1 ) ;
          if($pid = fork)
          {
              #Le pere
              close ECRIRE;
              &LirePipe();
              close LIRE;
          }
          #Le fils
          else
          {
                $code=&Generate();
     
                close(LIRE);
                for (my $i=0;$i<$tentative;$i++)
                {
                      $code=&Generate();
                      &verif($code);
                      push(@result,$code);
                      $num=$i;
                      print ECRIRE "$code";
                }
                close ECRIRE;
                foreach my $keys(keys %Trouve)
                {
                      print "$keys: trouve $Trouve{$keys} fois\n";
                }
          }
     
    }
    sub LirePipe()
    {
        $lu=<LIRE>;
        if ($lu ne "")
        {
              print "$lu\n";
        }
        else
        {
              exit(0);
        }
        sleep(1);
        &LirePipe();
    }
     
    sub verif()
    {
          $code_en_cours=$_[0];
          foreach(@result)
          {
                if($code_en_cours eq $_)
                {
                    $Trouve{$code_en_cours}++;
                }
          }
    }
     
    sub Generate()
    {
        my @tab;
        my @tab2;
        my $code;
        for($i=48;$i<=57;$i++){push(@tab,$i);}
    	  for($i=65;$i<=90;$i++){push(@tab,$i);}
    	  for($i=97;$i<=122;$i++){push(@tab,$i);}
    	  #$tab2[0]=chr($tab[Math.round((Math.random()*tab.length))]);
        $tab2[0]=chr($tab[sprintf("%0d",rand()*($#tab+1))]);
        for($i=1;$i<6;$i++)
    	  {
          $recur=ord($tab2[$i-1])%($#tab+1);
          $indice=sprintf("%0d",rand()*($#tab+1));
          $tab2[$i]=chr($tab[($recur+$indice)%($#tab+1)] );
      }
    $code=join("",@tab2);
    return $code;
    }
    Evidemment, ça ne marche pas.
    J'arrive bien à lire sur le pipe mais j'affiche tout d'un coups, et à la fin du script( c'est à dire quand la boucle qui calcule tous les codes s'achèvent)
    Pourquoi ? COmment remedier à ce problème ?
    Est-ce que j'utilise la bonne méthode ?

    Merci pour vos éclaircissement, j'aimerai bine mieux comprendre ces notions !!!

  2. #2
    Membre du Club
    Inscrit en
    Octobre 2005
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 47
    Points : 56
    Points
    56
    Par défaut
    Je n'ai aucune idée si c'est important (je n'ai pas bcp d'expérience avec IPC), mais tu pourrais essayer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $| = 1;     # ou le plus idiomatique: ++$|
    au début du script. Cela devrait supprimer l'utilisation d'un tampon qui est peut-être en train de ralentir la communication. Autrement dit, on print directement vers le pipe sans attendre.

    Cela n'a peut-être rien à voir, mais c'est ce que j'essayerais d'abord.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    801
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 801
    Points : 314
    Points
    314
    Par défaut
    ça n'a pas l'air de faire grande différence mais je l'ai mis qd même.
    Merci pour ton aide.

  4. #4
    Membre du Club
    Inscrit en
    Octobre 2005
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 47
    Points : 56
    Points
    56
    Par défaut
    Deuxième idée : la lecture récursive dans LirePipe() pourrait poser des pbs aussi.

    Pourquoi ne pas faire, à l'intérieur de la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    while ( <LIRE> ){
        print $_ . "\n";
        sleep(1);
    }

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    801
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 801
    Points : 314
    Points
    314
    Par défaut
    Alors j'ai appliquer tes suggestions sans succès.
    J'ai modifié un peu le script, san ssuccès non plus.
    Par contre, j'ai modifié l'affichage: au lieu de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    print "$pourcent %";
    J'ai écrit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    print "$pourcent %\n";
    Et ... ça marche

    voilà le script final:
    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
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
     
    #!c:\perl\bin\perl.exe
    use IO::Handle ;
     
    if($ARGV[0] eq '')
    {
        print "Il faut rentrer un nombre de tentatives";
    }
    else
    {
          $tentative=$ARGV[0];
          pipe ( LIRE , ECRIRE ) ;
          #ECRIRE -> autoflush ( 1 ) ;
          #LIRE -> autoflush ( 1 ) ;
          if($pid = fork)
          {
              #Le pere
              close ECRIRE;
              &LirePipe();
              close LIRE;
          }
          #Le fils
          else
          {
                $code=&Generate();
     
                close(LIRE);
                for (my $i=0;$i<$tentative;$i++)
                {
                      $code=&Generate();
                      &verif($code,$i);
                      push(@result,$code);
                      $num=$i;
                      print ECRIRE "$i\n";
                }
                close ECRIRE;
                foreach my $keys(keys %Trouve)
                {
                      print "$keys: trouve $Trouve{$keys} fois\n";
                }
          }
     
    }
    sub LirePipe()
    {
        while($lu=<LIRE>)
        {
              if ($lu ne "")
              {
                  chomp($lu);
                  $last_lu=$lu;
                  #print "last_pourcent: $last_pourcent    pourcent: $pourcent\n";
     
                  $pourcent=sprintf ("%0d",($lu/$tentative*100));
                  if($last_pourcent ne $pourcent)
                  {
                      system("cls");
                      print "$pourcent %\n";
                  }
                  $last_pourcent=$pourcent;
            }
            else
            {
                  exit(0);
            }
        }
    }
     
    sub verif()
    {
          $code_en_cours=$_[0];
          my $i=$_[1];
          foreach(@result)
          {
                if($code_en_cours eq $_)
                {
                    $Trouve{$code_en_cours}++;
                    print "\n$code_en_cours dejà trouvé $i eme combinaison!!!!\n";
                }
          }
    }
     
    sub Generate()
    {
        my @tab;
        my @tab2;
        my $code;
        for($i=48;$i<=57;$i++){push(@tab,$i);}
    	  for($i=65;$i<=90;$i++){push(@tab,$i);}
    	  for($i=97;$i<=122;$i++){push(@tab,$i);}
    	  #$tab2[0]=chr($tab[Math.round((Math.random()*tab.length))]);
        $tab2[0]=chr($tab[sprintf("%0d",rand()*($#tab+1))]);
        for($i=1;$i<6;$i++)
    	  {
          $recur=ord($tab2[$i-1])%($#tab+1);
          $indice=sprintf("%0d",rand()*($#tab+1));
          $tab2[$i]=chr($tab[($recur+$indice)%($#tab+1)] );
      }
    $code=join("",@tab2);
    return $code;
    }
    Si tu sais pourquoi ça marche maintenant, je serai heureux de le savoir.

  6. #6
    Membre du Club
    Inscrit en
    Octobre 2005
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 47
    Points : 56
    Points
    56
    Par défaut
    Je ne sais pas exactement. Je viens de jeter un coup d'oeil sur les
    docs (perldoc perlipc), qui confirment que le "++$|" est nécessaire en
    pareil cas.

    J'ai le soupçon que le pipe attendait la fin de la ligne pour envoyer
    réellement les données.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    801
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 801
    Points : 314
    Points
    314
    Par défaut
    ok j'en prends note.
    Merci de t'être penché sur le problème en tout cas.
    Bonne journée.

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

Discussions similaires

  1. Problème en essayant de lire le contenu d'un .lnk
    Par ybruant dans le forum API, COM et SDKs
    Réponses: 4
    Dernier message: 22/11/2018, 10h16
  2. [Perl]problème avec fork
    Par LE NEINDRE dans le forum Programmation et administration système
    Réponses: 1
    Dernier message: 23/09/2005, 16h31
  3. [perl]Problème tableau indexé
    Par LE NEINDRE dans le forum Langage
    Réponses: 8
    Dernier message: 25/08/2005, 22h24
  4. [PERL] problème désallocation de variable
    Par LE NEINDRE dans le forum Langage
    Réponses: 11
    Dernier message: 24/08/2005, 11h07
  5. [PERL] Problème lecture/écriture dans un fichier
    Par LE NEINDRE dans le forum Langage
    Réponses: 4
    Dernier message: 17/08/2005, 14h15

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