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

  FORUM HardWare.fr
  Programmation
  Perl

  [PERL] Erreure dans code. Algo?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[PERL] Erreure dans code. Algo?

n°2116820
Super_caro​tte
Posté le 15-12-2011 à 17:27:32  profilanswer
 

Bonjour,  :hello:  
 
J'ai fait un code qui simule le lancement en multithread de 9 jobs.
Ces jobs sont hiérarchisés comme suit:
1-->4,5-->7-->8 Donc 8 a pour père 7 qui a pour pere 4 et 5 qui ont pour père 1
2-->6-->8 Donc 8 a pour père 6 qui a pour père 2
3-->8,9 Donc 9 a pour père 3
Donc, 8 a pour père direct  7, 6 et 3.
 
Il fonctionne car mon tableau final contient bien l'ensemble de mes jobs (de 1 a 9)  :D  mais mon probleme vient du fait que mon tableau contenant  la liste des jobs "en cour de traitement " n'est pas vide a la fin du programme :pfff: . En effet, les jobs 7 et 8 sont toujours présent dedans.
Je ne vois pas pourquoi car mon code gère (il me semble) bien la destruction de ces valeurs. :(  
 
Si un curieux a le courage de se plonger dedans et parvient a trouver l’erreur, je suis preneur   ;)  
 
Merci,
Benjamin  
 
Voici le code:

Code :
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5. use Data::Dumper;
  6. use Parallel::ForkManager;
  7. use IPC::Shareable;
  8. ####################### PACKAGES ###########################
  9. package Job;
  10. my @listJob = ();
  11. my @tabProc = ();
  12. sub new {
  13.    my ($class, $ID_PROCESS, $ALIAS, $PERE, $FILS, $LOCK, $TYPE, $STARTED) = @_;
  14.    my $this = {};
  15.    bless($this, $class);
  16.  
  17.    $this->{ID_PROCESS} = $ID_PROCESS;
  18.    $this->{ALIAS} = $ALIAS;
  19.    $this->{PERE} = $PERE;
  20.    $this->{FILS} = $FILS;
  21.    $this->{LOCK} = $LOCK;
  22.    $this->{TYPE} = $TYPE;
  23.    $this->{STARTED} = $STARTED;
  24.  
  25.  
  26.   push(@listJob,$ID_PROCESS); 
  27.   push(@tabProc,$this);
  28. return $this;
  29.    }
  30.  
  31.  
  32. sub getID {
  33. my ($this) = @_;
  34. return $this->{ID_PROCESS};
  35. }
  36. sub getAlias {
  37. my ($this) = @_;
  38. return $this->{ALIAS};
  39. }
  40. sub getPere {
  41. my ($this) = @_;
  42. return $this->{PERE};
  43. }
  44. sub getFils {
  45. my ($this) = @_;
  46. return $this->{FILS};
  47. }
  48. sub getLock {
  49. my ($this) = @_;
  50. return $this->{LOCK};
  51. }
  52. 1;
  53. ####################### FIN PACKAGES ###########################
  54. ####################### MAIN ###########################
  55. my $pere;
  56. my $fils;
  57. my $LEVEL=0;
  58. $pere = undef;
  59. $fils = "4,5";
  60. my $proc1 = new Job( "1", "alias1", $pere, $fils, "0", "unknown", "0" );
  61. $pere = undef;
  62. $fils = "6";
  63. my $proc2 = new Job( "2", "alias2", $pere, $fils, "0", "unknown", "0" );
  64. $pere = undef;
  65. $fils = "8,9";
  66. my $proc3 = new Job( "3", "alias3", $pere, $fils, "0", "unknown", "0" );
  67. $pere = "1";
  68. $fils = "7";
  69. my $proc4 = new Job( "4", "alias4", $pere, $fils, "0", "unknown", "0" );
  70. $pere = "1";
  71. $fils = "7";
  72. my $proc5 = new Job( "5", "alias5", $pere, $fils, "0", "unknown", "0" );
  73. $pere = "2";
  74. $fils = "8";
  75. my $proc6 = new Job( "6", "alias6", $pere, $fils, "0", "unknown", "0" );
  76. $pere = "4,5";
  77. $fils = "8";
  78. my $proc7 = new Job( "7", "alias7", $pere, $fils, "0", "unknown", "0" );
  79. $pere = "7,6,3";
  80. $fils = undef;
  81. my $proc8 = new Job( "8", "alias8", $pere, $fils,, "0", "unknown", "0" );
  82. $pere = "3";
  83. $fils = undef;
  84. my $proc9 = new Job( "9", "alias9", $pere, $fils, "0", "unknown", "0" );
  85. print "listJob : @listJob\n";
  86. print Data::Dumper::Dumper @tabProc;
  87. foreach my $row (@tabProc)
  88. {
  89.  if ($row->{PERE} eq undef)
  90.  {
  91.   $row->{PERE} = "NULL";
  92.  }else
  93.  {
  94.   $row->{PERE} =~ s/,/ /g;
  95.  }
  96.  if ($row->{FILS} eq undef)
  97.  {
  98.   $row->{FILS} = "NULL";
  99.  }
  100.  else
  101.  {
  102.   $row->{FILS} =~ s/,/ /g;
  103.  }
  104.  if ($row->{PERE} eq "NULL" )
  105.  {
  106.   $row->{TYPE} = "PERE-0";
  107.  }
  108.  else
  109.  {
  110.   if ($row->{FILS} eq "NULL" )
  111.   {
  112.    $row->{TYPE} = "FILS";
  113.   }
  114.   else
  115.   {
  116.    $row->{TYPE} = "PERE";
  117.   }
  118.   $row->{STARTED} = 0;
  119.  }
  120.  $LEVEL+=1;
  121. }
  122. print Data::Dumper::Dumper @tabProc;
  123. print "LEVEL : $LEVEL\n";
  124. my $RETOUR;
  125. my @tabProc_temp=();
  126. my @tabProcEnCours;
  127. my @tabProcFini;
  128. my $i=0;
  129. my %options = (
  130.     create    => 1,
  131.     exclusive => 0,
  132.     mode      => 0644,
  133.     destroy   => 0,
  134. );
  135. print "tabProcFini: @tabProcFini\n";
  136. print "tabProcEnCours: @tabProcEnCours\n";
  137. print "tabProc_temp: @tabProc_temp\n";
  138. tie @tabProc_temp, 'IPC::Shareable', 'tie1', \%options;
  139. tie @tabProcEnCours, 'IPC::Shareable', 'tie2', \%options;
  140. tie @tabProcFini, 'IPC::Shareable', 'tie3', \%options;
  141. @tabProcEnCours=();
  142. @tabProcFini=();
  143. @tabProc_temp=@tabProc;  #tabProc_temp contient la copie de la liste des processus existants.
  144. print "tabProc_temp: @tabProc_temp\n";
  145. my $pm = new Parallel::ForkManager(10);
  146. while( @tabProc_temp )  #Tant que le tableau des processus n'est pas vide
  147. {
  148. $i=0;
  149.  foreach my $row (@tabProc_temp)  #pour chaque processus
  150.  {
  151.   # print "tabProcEnCours: @tabProcEnCours\n";
  152.   # print "tabProcFini: @tabProcFini\n";
  153.   my $ID = $row->{ID_PROCESS};
  154.   my $LOCK = $row->{LOCK};
  155.   my $TYPE = $row->{TYPE};
  156.   my $PERE = $row->{PERE};
  157.   print "PROCESS $ID lets work on it! \n";
  158.   my %hashEncours = map{$_ => 1} (@tabProcEnCours);
  159.   # print "ID : $ID\n";
  160.   # print "tabProc_temp : \n";
  161.   # print Data::Dumper::Dumper @tabProc_temp;
  162.    print "tabProcFini : @tabProcFini\n";
  163.    print "tabProcEnCours : @tabProcEnCours\n\n";
  164.   if (exists $hashEncours{$ID})  #si le processus est en cour de traitemet
  165.   {
  166.    print "PROCESS $ID already forked! \n";
  167.    print "PROCESS ","$ID Let's try another process \n\n";
  168.   }else
  169.   {
  170.    if ($LOCK == "0" ) #si le processus est bloqué (dans ce test code, il ne l'est jamais)
  171.    {
  172.     $RETOUR = "Not OK";
  173.     if ($RETOUR eq "OK" ) #si le retout est OK (dans ce test code, il ne l'est jamais)
  174.     {
  175.      print "PROCESS","$ID is Running \n";
  176.      push(@tabProcFini,$ID);
  177.      print "\n";
  178.     }
  179.     else
  180.     {
  181.      print "PROCESS ","$ID is Stopped \n\n";
  182.      if ($TYPE eq "PERE-0" ) #si le processus en cour de traitement est tout en haut de l'arbre (donc que lui meme n'a pas de pere)
  183.      {
  184.       $pm->start and next; # je lance un fork
  185.       my $ID_inFork = $ID;
  186.       (tied @tabProcEnCours)->shlock;
  187.       push(@tabProcEnCours,$ID_inFork);  #j'ajoute le processus dans le tableau des processus en cour de traitement
  188.       (tied @tabProcEnCours)->shunlock;
  189.       sleep 3;  # je fais un sleep pour simuler le temps de traitement du processus
  190.       (tied @tabProc_temp)->shlock;
  191.       @tabProc_temp = @tabProc_temp[0..($i-1),($i+1)..$#tabProc_temp]; #j'enleve le processus du talbeau contenant la liste des processus
  192.       (tied @tabProc_temp)->shunlock;
  193.       (tied @tabProcFini)->shlock;
  194.       push(@tabProcFini,$ID_inFork);  # j'ajoute le processus dans le tableau contenant les processus fini
  195.       (tied @tabProcFini)->shunlock;
  196.       (tied @tabProcEnCours)->shlock;
  197.       @tabProcEnCours = @tabProcEnCours[0..($i-1),($i+1)..$#tabProcEnCours]; #j'enleve le processus du talbeau contenant la liste des processus en cour
  198.       (tied @tabProcEnCours)->shunlock;
  199.       # print "tabProc_temp : \n";
  200.       # print Data::Dumper::Dumper @tabProc_temp;
  201.       # print "tabProcFini : @tabProcFini\n";
  202.       # print "tabProcEnCours : @tabProcEnCours\n\n";
  203.       print "PROCESS ","$ID_inFork well started outside \n\n";
  204.       $pm->finish;
  205.      }else
  206.      {
  207.       my @tab1 = split(/ /,$PERE);
  208.       my $tailletab1 = scalar @tab1;
  209.       my @tab2=@tabProcFini;
  210.       my %hash = map{$_ => 1} (@tab1, @tab2);
  211.       #print "hash : \n";
  212.       #print Data::Dumper::Dumper %hash;
  213.       my @tab = keys %hash;
  214.       my $nombre_elements_commun = @tab1 + @tab2 - @tab;
  215.       #print "tab1 : @tab1`\n";
  216.       #print "tab2 : @tab2`\n";
  217.       #print "tab : @tab`\n";
  218.       #print "tailletab1 : $tailletab1`\n";
  219.       #print "nombre_elements_commun : $nombre_elements_commun`\n";
  220.       if($nombre_elements_commun == $tailletab1)
  221.       {
  222.        $pm->start and next; # je lance un fork
  223.        my $ID_inFork = $ID;
  224.        my $PERE_inFork =$PERE;
  225.        (tied @tabProcEnCours)->shlock;
  226.        push(@tabProcEnCours,$ID_inFork); #j'ajoute le processus dans le tableau des processus en cour de traitement
  227.        (tied @tabProcEnCours)->shunlock;
  228.        print "PROCESS ","$ID_inFork Parents: $PERE_inFork \n";
  229.        print "PROCESS ","$ID_inFork Les elements de la liste \"PERE\" du process $ID_inFork sont tous présents dans le tableau \@tabProcFini \n\n";
  230.        sleep 3; # je fais un sleep pour simuler le temps de traitement du processus
  231.        (tied @tabProc_temp)->shlock;
  232.        @tabProc_temp = @tabProc_temp[0..($i-1),($i+1)..$#tabProc_temp]; #j'enleve le processus du talbeau contenant la liste des processus
  233.        (tied @tabProc_temp)->shunlock;
  234.        (tied @tabProcFini)->shlock;
  235.        push(@tabProcFini,$ID_inFork);  # j'ajoute le processus dans le tableau contenant les processus fini
  236.        (tied @tabProcFini)->shunlock;
  237.        (tied @tabProcEnCours)->shlock;
  238.        @tabProcEnCours = @tabProcEnCours[0..($i-1),($i+1)..$#tabProcEnCours]; #j'enleve le processus du talbeau contenant la liste des processus en cour
  239.        (tied @tabProcEnCours)->shunlock;
  240.        #print "INSIDE ID_inFork : $ID_inFork\n";
  241.        #print "tabProc_temp : \n";
  242.        #print Data::Dumper::Dumper @tabProc_temp;
  243.        #print "INSIDE tabProcFini : @tabProcFini\n";
  244.        #print "INSIDE tabProcEnCours : @tabProcEnCours\n\n";
  245.        print "PROCESS ","$ID_inFork well started inside\n\n";
  246.        $pm->finish;
  247.       }else
  248.       {
  249.        # print "PROCESS $ID PERE =  $PERE \n";
  250.        print "PROCESS ","$ID Les elements de la liste \"PERE\" du process $ID NE sont PAS tous présents dans le tableau \@tabProcFini \n";
  251.        print "PROCESS ","$ID Let's try another process \n\n";
  252.       }
  253.      }
  254.      $RETOUR = "OK";
  255.      if ($RETOUR ne "OK" )
  256.      {
  257.       print "PROCESS","$ID not started \n";
  258.       exit(1);
  259.      }
  260.     }
  261.    }
  262.    else
  263.    {
  264.     print "$ID Locked !!! \n";
  265.     push(@tabProcFini,$ID);
  266.     print "\n";
  267.    }
  268.   }
  269.   sleep 1;
  270.   $i++;
  271.   #print "tabProc_temp : @tabProc_temp\n";
  272.   # print "tabProc_temp : \n";
  273.   # print Data::Dumper::Dumper @tabProc_temp;
  274.   # print "tabProcFini : @tabProcFini\n";
  275.   # print "tabProcEnCours : @tabProcEnCours\n\n";
  276.  }
  277. }
  278. $pm->wait_all_children;
  279. print "tabProc_temp : \n";
  280. print Data::Dumper::Dumper @tabProc_temp;
  281. print "tabProcFini : @tabProcFini\n";
  282. print "tabProcEnCours : @tabProcEnCours\n\n";


Message édité par Super_carotte le 15-12-2011 à 17:49:12
mood
Publicité
Posté le 15-12-2011 à 17:27:32  profilanswer
 

n°2116916
Super_caro​tte
Posté le 16-12-2011 à 12:03:32  profilanswer
 

J'ai trouvé l'erreure.
Elle est due a mon $i qui ne fonctionne pas correctement.
 
En effet, en remplaçant:

Code :
  1. (tied @tabProcEnCours)->shlock;
  2. @tabProcEnCours = @tabProcEnCours[0..($i-1),($i+1)..$#tabProcEnCours]; #j'enleve le processus du talbeau contenant la liste des processus en cour
  3. (tied @tabProcEnCours)->shunlock;


 
Par:

Code :
  1. (tied @tabProcEnCours)->shlock;
  2. my %hashTabProcEnCours = map{$_ => 1} (@tabProcEnCours);
  3. delete $hashTabProcEnCours{$ID_inFork};
  4. @tabProcEnCours=keys(%hashTabProcEnCours);
  5. (tied @tabProcEnCours)->shunlock;


 
ça fonctionne  :D  
 


Message édité par Super_carotte le 16-12-2011 à 12:05:16

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

  [PERL] Erreure dans code. Algo?

 

Sujets relatifs
[algo] Toutes les combinaisons d'un tableau à 2 dimensions?Bluegriffon - probleme de code
[C#] erreur dans le codecode défaillant
Mise à jour automatique de code / script[Algo] + [Python] Analyse d'une formule
Code A Provenance de train + numeroPop-up facebook, un code quelque part ?
Code de presentation[jQuery] Code non exécuté
Plus de sujets relatifs à : [PERL] Erreure dans code. Algo?


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