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

  FORUM HardWare.fr
  Programmation
  Perl

  PERL - Communication processus pere/fils

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

PERL - Communication processus pere/fils

n°2116405
Super_caro​tte
Posté le 13-12-2011 à 09:43:40  profilanswer
 

Bonjour,
 
La, je bloque vraiment.  :??:  
Je fait un code qui utilise Parallel:ForkManager afin de pouvoir lancer des processus fils.
Ce que je voudrai, c'est que mes processus fils puissent modifier (en fait supprimer une case) un tableau qui est dans le main().
 
J'ai vu ces deux sujets:
ici et la
 
Mais je n'y comprend pas grand chose. Ces bibliothèques sont bien complexe.  :whistle:  
 
Exemple de ce que je souhaiterai:

Code :
  1. #!/opt/perl/bin/perl
  2. use strict;
  3. use warnings;
  4. use ForkManager;
  5. my $pm = Parallel::ForkManager->new(10);        #nombre de processus max
  6. $pm->run_on_finish( sub {
  7.     printf "%s : Process completed: @_\n", scalar localtime
  8. });
  9. my @tableau1=(1,2,3,4,5,6,7,8,9);
  10. while(@tableau1 n'est pas vide) {
  11. foreach(@tableau1){
  12.     $pm->start($i) and next;
  13.     supprimer l'element en cours de lecture de @tableau1
  14.     $pm->finish;
  15. }
  16. }
  17. printf "%s: Waiting for some child to finish\n", scalar localtime;
  18. $pm->wait_all_children;
  19. printf "%s: All processes finished.\n", scalar localtime;


 
Si quelqu'un arrive a trouver une solution a ce probleme, je lui en serait vraiment reconnaissant.  :wahoo:  
(Sachant que je ne peux pas utiliser la communication par fichier car ce ne serait pas "suffisamment propre".)
Cordialement,
Benjamin
 
PS:
Si quelqu’un est curieux de savoir les raison de ces questions:
J’essaie de mettre en place un multi thread sur le code suivant.
Ce code simule un démarrage de Jobs de façon hiérarchisé.
Donc le code suivant fonctionne mais j'aimerai maintenant y appliquer du multi thread lors du démarrage des jobs (actuellement simulé par un "sleep rand 5;" )via la bibliothèque ForkManager.

Code :
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5. use Data::Dumper;
  6. use Parallel::ForkManager;
  7. ####################### PACKAGES ###########################
  8. package Job;
  9. my @listJob = ();
  10. my @tabProc = ();
  11. sub new {
  12.    my ($class, $ID_PROCESS, $ALIAS, $PERE, $FILS, $LOCK, $TYPE, $STARTED) = @_;
  13.    my $this = {};
  14.    bless($this, $class);
  15.  
  16.    $this->{ID_PROCESS} = $ID_PROCESS;
  17.    $this->{ALIAS} = $ALIAS;
  18.    $this->{PERE} = $PERE;
  19.    $this->{FILS} = $FILS;
  20.    $this->{LOCK} = $LOCK;
  21.    $this->{TYPE} = $TYPE;
  22.    $this->{STARTED} = $STARTED;
  23.  
  24.  
  25.   push(@listJob,$ID_PROCESS); 
  26.   push(@tabProc,$this);
  27. return $this;
  28.    }
  29.  
  30.  
  31. sub getID {
  32. my ($this) = @_;
  33. return $this->{ID_PROCESS};
  34. }
  35. sub getAlias {
  36. my ($this) = @_;
  37. return $this->{ALIAS};
  38. }
  39. sub getPere {
  40. my ($this) = @_;
  41. return $this->{PERE};
  42. }
  43. sub getFils {
  44. my ($this) = @_;
  45. return $this->{FILS};
  46. }
  47. sub getLock {
  48. my ($this) = @_;
  49. return $this->{LOCK};
  50. }
  51. 1;
  52. ####################### FIN PACKAGES ###########################
  53. ####################### MAIN ###########################
  54. my $pere;
  55. my $fils;
  56. my $LEVEL=0;
  57. $pere = undef;
  58. $fils = "4,5";
  59. my $proc1 = new Job( "1", "alias1", $pere, $fils, "0", "unknown", "0" );
  60. $pere = undef;
  61. $fils = "6";
  62. my $proc2 = new Job( "2", "alias2", $pere, $fils, "0", "unknown", "0" );
  63. $pere = undef;
  64. $fils = "8,9";
  65. my $proc3 = new Job( "3", "alias3", $pere, $fils, "0", "unknown", "0" );
  66. $pere = "1";
  67. $fils = "7";
  68. my $proc4 = new Job( "4", "alias4", $pere, $fils, "0", "unknown", "0" );
  69. $pere = "1";
  70. $fils = "7";
  71. my $proc5 = new Job( "5", "alias5", $pere, $fils, "0", "unknown", "0" );
  72. $pere = "2";
  73. $fils = "8";
  74. my $proc6 = new Job( "6", "alias6", $pere, $fils, "0", "unknown", "0" );
  75. $pere = "4,5";
  76. $fils = "8";
  77. my $proc7 = new Job( "7", "alias7", $pere, $fils, "0", "unknown", "0" );
  78. $pere = "7,5,6,3";
  79. $fils = undef;
  80. my $proc8 = new Job( "8", "alias8", $pere, $fils,, "0", "unknown", "0" );
  81. $pere = "3";
  82. $fils = undef;
  83. my $proc9 = new Job( "9", "alias9", $pere, $fils, "0", "unknown", "0" );
  84. print "listJob : @listJob\n";
  85. print Data::Dumper::Dumper @tabProc;
  86.  foreach my $row (@tabProc)
  87. {
  88.  if ($row->{PERE} eq undef)
  89.  {
  90.   $row->{PERE} = "NULL";
  91.  }else
  92.  {
  93.   $row->{PERE} =~ s/,/ /g;
  94.  }
  95.  if ($row->{FILS} eq undef)
  96.  {
  97.   $row->{FILS} = "NULL";
  98.  }
  99.  else
  100.  {
  101.   $row->{FILS} =~ s/,/ /g;
  102.  }
  103.  if ($row->{PERE} eq "NULL" )
  104.  {
  105.   $row->{TYPE} = "PERE-0";
  106.  }
  107.  else
  108.  {
  109.   if ($row->{FILS} eq "NULL" )
  110.   {
  111.    $row->{TYPE} = "FILS";
  112.   }
  113.   else
  114.   {
  115.    $row->{TYPE} = "PERE";
  116.   }
  117.   $row->{STARTED} = 0;
  118.  }
  119.  $LEVEL+=1;
  120. }
  121. print Data::Dumper::Dumper @tabProc;
  122. print "LEVEL : $LEVEL\n";
  123. my $RETOUR;
  124. my @tabProc_temp=@tabProc;
  125. my @tabProcFini=();
  126. my $i=0;
  127. while( @tabProc_temp )
  128. {
  129. $i=0;
  130.  foreach my $row (@tabProc_temp)
  131.  {
  132.   if ($row->{LOCK} == 0)
  133.   {
  134.    $RETOUR = "Not OK";
  135.    print "PROCESS $row->{ID_PROCESS} lets work on it! \n";
  136.    if ($RETOUR eq "OK" )
  137.    {
  138.     print "PROCESS","$row->{ID_PROCESS} is Running \n";
  139.     push(@tabProcFini,$row->{ID_PROCESS});
  140.     @tabProc_temp = @tabProc_temp[0..($i-1),($i+1)..$#tabProc_temp];
  141.     print "\n";
  142.    }
  143.    else
  144.    {
  145.     print "PROCESS ","$row->{ID_PROCESS} is Stopped \n";
  146.     if ($row->{TYPE} eq "PERE-0" )
  147.     {
  148.      sleep rand 5;
  149.      print "PROCESS ","$row->{ID_PROCESS} well started \n\n";
  150.      push(@tabProcFini,$row->{ID_PROCESS});
  151.      @tabProc_temp = @tabProc_temp[0..($i-1),($i+1)..$#tabProc_temp];
  152.     }else
  153.     {
  154.      my @tab1 = split(/ /,$row->{PERE});
  155.      my $tailletab1 = scalar @tab1;
  156.      my @tab2=@tabProcFini;
  157.      my %hash = map{$_ => 1} (@tab1, @tab2);
  158.      my @tab = keys %hash;
  159.      my $nombre_elements_commun = @tab1 + @tab2 - @tab;
  160.      if($nombre_elements_commun == $tailletab1)
  161.      {
  162.       print "PROCESS ","$row->{ID_PROCESS} Parents: $row->{PERE} \n";
  163.       print "PROCESS ","$row->{ID_PROCESS} Les elements de la liste \"PERE\" du process $row->{ID_PROCESS} sont tous présents dans le tableau \@tabProcFini \n";
  164.       sleep rand 5;
  165.       print "PROCESS ","$row->{ID_PROCESS} well started \n\n";
  166.       push(@tabProcFini,$row->{ID_PROCESS});
  167.       @tabProc_temp = @tabProc_temp[0..($i-1),($i+1)..$#tabProc_temp];
  168.      }else
  169.      {
  170.       print "PROCESS ","$row->{ID_PROCESS} Les elements de la liste \"PERE\" du process $row->{ID_PROCESS} NE sont PAS tous présents dans le tableau \@tabProcFini \n";
  171.       print "PROCESS ","$row->{ID_PROCESS} Let's try another process \n\n";
  172.      }
  173.     }
  174.     $RETOUR = "OK";
  175.     if ($RETOUR ne "OK" )
  176.     {
  177.      print "PROCESS","$row->{ID_PROCESS} not started \n";
  178.      exit(1);
  179.     }
  180.    }
  181.   }
  182.   else
  183.   {
  184.    print "$row->{ID_PROCESS} Locked !!! \n";
  185.    push(@tabProcFini,$row->{ID_PROCESS});
  186.    @tabProc_temp = @tabProc_temp[0..($i-1),($i+1)..$#tabProc_temp];
  187.    print "\n";
  188.   }
  189.  $i++;
  190.  #print "tabProc_temp : @tabProc_temp\n";
  191.  print "tabProcFini : @tabProcFini\n\n";
  192.  }
  193. }


 
Toutes les propositions sont les bienvenue, je sèche vraiment  :ange:


Message édité par Super_carotte le 13-12-2011 à 09:46:33
mood
Publicité
Posté le 13-12-2011 à 09:43:40  profilanswer
 

n°2116466
gilou
Modérateur
Modzilla
Posté le 13-12-2011 à 13:24:43  profilanswer
 

Vu que dans le modèle standard d'un fork, le processus fils ne partage pas l'environnement mémoire avec son processus père, mais en fait une copie, il n'y a aucune chance que les processus fils accèdent au tableau @tableau1.
 
Une solution à ce problème est décrite ici: http://docstore.mik.ua/orelly/perl [...] h16_13.htm
Bon, c'est pas portable dans tous les environnements, donc pas portable sous windows par exemple.
 

Citation :

J’essaie de mettre en place un multi thread sur le code suivant.

Il y a une raison particulière pour réinventer la roue, plutôt qu'utiliser une solution éprouvée comme Coro?
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2116502
Super_caro​tte
Posté le 13-12-2011 à 15:51:51  profilanswer
 

Bonjour,
 
Tout d'abord, merci pour cette réponse.
 
Ce que j'essaie de faire, c'est de mettre en place un script de démarrage de jobs de façon hiérarchisé.
Donc j'ai créé un code (cf ci-dessus) qui fait cela mais sans parallélisation. Maintenant que ce code fonctionne, j’essaie d'y implanter la parallélisation.
 
Mais étant un débutant en perl, il est fort possible que ma méthode ou que les bibliothèques utilisée ne soient pas les bonnes.
 
Pensez vous que coro puisse gérer un lancement hiérarchisé d'action en parallèle? En quoi est-il different de ForkManager?
En effet, dans sa description j'ai pu lire:  

Citation :

They are similar to kernel threads but don't (in general) run in parallel at the same time even on SMP machines


Du coup, cela ne signifie t'il pas que la parallélisation ne fonctionne pas sur coro?
 
Merci,
Benjamin

n°2116507
gilou
Modérateur
Modzilla
Posté le 13-12-2011 à 16:17:35  profilanswer
 

Comme dit dans une doc, "Coro implements cooperative multitasking/multithreading with explicit task switching, while threads implements scheduled multitasking/multithreading. The advantage of Coro is that you don't get any race conditions. The advantage of threads is that you can get true parallelism across more than one CPU."
 
Mais si vous avez besoins de threads, pourquoi ne pas avoir utilisé ce qui existait déjà dans perl?
Bon en tout cas, si vous êtes sur une architecture de type unix, votre approche par des fork, plus l'utilisation de mêmoire partagée devrait suffire. Si vous êtes sous Win32, vaut mieux pas penser à cette approche, vu déjà que fork y est émulé par perl. Il doit y avoir moyen de faire ce que vous voulez, mais de manière OS dépendante avec les modules WIN32.
 
A+,


Message édité par gilou le 13-12-2011 à 16:41:15

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2116587
Super_caro​tte
Posté le 14-12-2011 à 10:01:40  profilanswer
 

Bonjour,
Mon code doit être multi-platefrome car il doit tourner sur des UNIX et des Win32.  
Donc pas de fork car ça doit pouvoir tourner sur du win32 et pas d'utilisation de "modules WIN32" car ça doit tourner sur de Unix.
 
Il me reste quelle option ?  :??:

n°2116615
gilou
Modérateur
Modzilla
Posté le 14-12-2011 à 11:49:24  profilanswer
 

De partir sur Coro et de laisser tomber le vrai parallélisme (ou de rester avec fork, mais de pas compter dessus sur une plateforme WIN32, ou de toute façon, IPC::Shareable n'a pas l'air d'être supporté), ou éventuellement essayer d'utiliser les threads Perl (mais comme j'ai jamais eu l'occasion de les utiliser dans mes programmes, je en sais s'ils implémentent un vrai parallélisme sous WIN32).
La le problème est pas limité à Perl: a moins de passer par des librairies spécialisées et multiplateformes ajoutant le support du vrai parallélisme la ou il est utile, le problème est assez général à tout code devant fonctionner sur des OS différents.
Il reste aussi la possibilité d'écrire du code OS dépendant avec un test sur l'architecture ($^O) pour décider de ce qui est appelé (un équivalent des ifdef du C) et en ce cas, la lecture de ceci: http://www.perlmonks.org/bare/?node_id=331029 n'est pas inutile pour la partie mémoire partagée et fork sous Windows (le bug est peut être corrigé depuis)
A+,


Message édité par gilou le 14-12-2011 à 13:27:37

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2116894
Super_caro​tte
Posté le 16-12-2011 à 09:15:49  profilanswer
 

Re bonjour,  :hello:  
 
Après en avoir parlé avec les collègues, il s’avère que le code ne sera démarré que depuis des Red Hat.
En fait, la Red Hat va se contenter de lancer des ordres de façon parallélisé aux différents serveurs (unix, linux et win32).
 
Donc il me semble que al solution forkManager reste viable. (tant mieux, coro ne m'a pas semblé evidant a utilisé et je n'ai pas trouvé beaucoup d'exemples sur son utilisation).
 
Merci de m'avoir donné ton avis,  ;)  
 
Cordialement,
Benjamin.


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

  PERL - Communication processus pere/fils

 

Sujets relatifs
Communication programmes C[C#] savoir si un processus est en train de réfléchir, possible ?
[C][Gnu] info utilisation memoire, processeur et swap [résolu]logger ouverture fermeture processus
[Résolu] Gestion d'un Top10 en %hash et de la "casse"[Résolu] Question sur l'optimisation pour compter le nombre de ligne
communication PHP via socket : permission deniedCommunication PHP / C++ via un socket UNIX => blocage read/write
Communication avec port RS232 : Récupération de valeurs chiffréesperl - lister les fichiers d'un rep
Plus de sujets relatifs à : PERL - Communication processus pere/fils


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