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

  FORUM HardWare.fr
  Programmation
  Perl

  Fork et die

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Fork et die

n°1896535
bichtoubar​d
Posté le 18-06-2009 à 10:55:40  profilanswer
 

Bonjour,
 
J'ai un programme qui appelle des connexions SSH sur différents serveurs dans une boucle.
Pour simuler un timeout j'utilise des fork, et si le timeout arrive a expiration je tue le fils.
Si la connexion plante ou qu'il y a un problème, je demande également au fils de se tuer.  
 
Mon problème est que si je lui demande de se tuer a l'intérieur d'une fonction qui est dans le code mais a l'extérieur du "if $fork == 0" le programme se tue, si je place la fonction à l'intérieur par contre j'ai le comportement souhaité (mais j'aimerai bien mettre mes fonctions a l'extérieur dans un souci de lisibilité).
 
En bref, le comportement suivant est-il normal ?
 

Code :
  1. Exemple 1 : Le programme se tue
  2. for my $hosts (@hosts){
  3. my $pid = fork;
  4. if ($pid == 0) {
  5.  &kill-me();
  6. }
  7. }
  8. sub kill-me {
  9. die;
  10. }
  11. Exemple 2 : Le fils meurt
  12. for my $hosts (@hosts){
  13. my $pid = fork;
  14. if ($pid == 0) {
  15.  sub kill-me {
  16.   die;
  17.  }
  18.  &kill-me();
  19. }
  20. }


mood
Publicité
Posté le 18-06-2009 à 10:55:40  profilanswer
 

n°1896692
Taz
bisounours-codeur
Posté le 18-06-2009 à 17:52:05  profilanswer
 

ben fork te donnes le pid tu fils créé.

n°1896696
gilou
Modérateur
Modosaurus Rex
Posté le 18-06-2009 à 17:59:49  profilanswer
 

Pourquoi ne pas passer par kill?
J'ai pas testé, mais je ferais ainsi pour ton premier cas

Code :
  1. for my $hosts (@hosts) {
  2.    my $pid = fork;
  3.    if ($pid == 0) {
  4.        &kill-me($pid);
  5.    }
  6. }
  7. sub kill-me {
  8.    my $pid = shift;
  9.    kill 9, $pid;
  10. }


 
Je ne sais pas trop ce que signifie

Code :
  1. if ($pid == 0) {
  2.  sub kill-me {
  3.   die;
  4.  }


car habituellement, on ne définit pas un sub à l'intérieur d'une autre procédure.
Le fils meurt et pas le père? bizarre.
A+,

Message cité 2 fois
Message édité par gilou le 18-06-2009 à 18:08:04

---------------
There's more than what can be linked! --  Le capitaine qui ne veut pas obéir à la carte finira par obéir aux récifs. -- Il ne faut plus dire Sarkozy, mais Sarkozon -- (╯°□°)╯︵ ┻━┻
n°1896762
Taz
bisounours-codeur
Posté le 18-06-2009 à 22:02:30  profilanswer
 

gilou a écrit :

Pourquoi ne pas passer par kill?
J'ai pas testé, mais je ferais ainsi pour ton premier cas

Code :
  1. for my $hosts (@hosts) {
  2.    my $pid = fork;
  3.    if ($pid == 0) {
  4.        &kill-me($pid);
  5.    }
  6. }
  7. sub kill-me {
  8.    my $pid = shift;
  9.    kill 9, $pid;
  10. }


 
Je ne sais pas trop ce que signifie

Code :
  1. if ($pid == 0) {
  2.  sub kill-me {
  3.   die;
  4.  }


car habituellement, on ne définit pas un sub à l'intérieur d'une autre procédure.
Le fils meurt et pas le père? bizarre.
A+,


T'es obligé de kill. Sinon tu peux tenter des fourberies avec alarm + nettoyage des fils du fils ...

n°1896822
bichtoubar​d
Posté le 19-06-2009 à 09:26:26  profilanswer
 

gilou a écrit :

Pourquoi ne pas passer par kill?
J'ai pas testé, mais je ferais ainsi pour ton premier cas

Code :
  1. for my $hosts (@hosts) {
  2.    my $pid = fork;
  3.    if ($pid == 0) {
  4.        &kill-me($pid);
  5.    }
  6. }
  7. sub kill-me {
  8.    my $pid = shift;
  9.    kill 9, $pid;
  10. }




 
 
En fait peut importe comment on tue le fils, tu peux envoyer un signal ou bien lui demander de faire ça lui même.
 
Dans mon cas, je gère effectivement les timeout des fils en envoyant des signaux de fin, mais là c'est dans le cas ou par exemple la connexion ssh plante, pour ne pas lancer les commandes suivantes de copies de fichier.
Dans ce cas le père ne peut pas savoir le statut de la commande, donc c'est au fils de se terminer, d'où le die.
 
Exemple :

Code :
  1. $scp = Net::SCP->new("$host", "user" ) or die $scp->{errstr};
  2. $scp->get("/tmp/mylist.tmp","$inventaire" ) or $scp->{errstr};


 

gilou a écrit :


Je ne sais pas trop ce que signifie

Code :
  1. if ($pid == 0) {
  2.  sub kill-me {
  3.   die;
  4.  }


car habituellement, on ne définit pas un sub à l'intérieur d'une autre procédure.
Le fils meurt et pas le père? bizarre.
A+,


 
Justement c'est ça qui le chagrine, si je ne définie pas le sub à l'intérieur de la procédure contenant le "if $pid == 0", ce n'est pas le fils qui meurt, mais le père.
Dans le cas où j'ai 150 serveurs à traiter c'est gênant, car dès qu'une connexion échoue, je dois tout recommencer.
 
Le problème n'est pas handicapant outre mesure car en mettant les subs a l'intérieur du code du fils ça fonctionne mais je préférerais déclarer mes subs ailleurs..
 
Pour le peu que je connais du fork, il me semblait que le code était dupliqué :
- Est-ce tout le code ou juste le code dans lequel on définit "if $pid==0" ?
- Est-ce possible que le fils appelle la fonction du père plutôt que de dupliquer le code ?


Message édité par bichtoubard le 19-06-2009 à 09:27:43
n°1897103
gilou
Modérateur
Modosaurus Rex
Posté le 19-06-2009 à 18:56:45  profilanswer
 

Comme je code en java ces temps ci, je n'avais pas les idées nettes.
 
Je procéderais ainsi:
 

Code :
  1. #/usr/bin/perl
  2.  
  3. my $father = $$;
  4.  
  5. for my $host (1..6) {
  6.    if ($$ == $father) { #si on veut éviter que les fils ne forkent eux aussi
  7.        fork;
  8.    }
  9. }
  10. &byebye();
  11.  
  12. sub byebye {
  13.    if ($$ != $father) {
  14.        exit(0); #ou die, qui est plus verbeux
  15.    }
  16. }


Ici, byebye est une fonction commune, qui ne tuera que les fils
A+,


---------------
There's more than what can be linked! --  Le capitaine qui ne veut pas obéir à la carte finira par obéir aux récifs. -- Il ne faut plus dire Sarkozy, mais Sarkozon -- (╯°□°)╯︵ ┻━┻
n°1897115
gilou
Modérateur
Modosaurus Rex
Posté le 19-06-2009 à 19:29:27  profilanswer
 

Noter aussi qu'on peut passer par un pointeur de fonction:
 

Code :
  1. #/usr/bin/perl
  2.  
  3. sub do_nothing {}
  4. sub do_exit {exit(0);}
  5. my $functionref = \&do_nothing;
  6.  
  7. for my $host (1..3) {
  8.        my $pid = fork;
  9.        if ($pid == 0) {
  10.            $functionref = \&do_exit;
  11.        }
  12. }
  13.  
  14. &$functionref();


Noter qu'ici, je n'ai pas mis le code qui évite au fils de forker, pour plus de clarté.
&$functionref() sera un appel a do_nothing dans le père et a do_exit dans les fils.
 
A+,
 


---------------
There's more than what can be linked! --  Le capitaine qui ne veut pas obéir à la carte finira par obéir aux récifs. -- Il ne faut plus dire Sarkozy, mais Sarkozon -- (╯°□°)╯︵ ┻━┻

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

  Fork et die

 

Sujets relatifs
[C] Fork et PipeUtilisation de Fork: plusieurs boucles executées en parrallèle
Script bash; fork: Ne peut allouer de la mémoire[Shell] fork et &
[C++] Problème FORKfork() empêche les printf ?!
processus fils engendré par un forkFork et programme aléatoire
Algorithme parallélisé: Je n'arrive pas à l'écrire avec fork()fork et SIGCHLD (RESOLU)
Plus de sujets relatifs à : Fork et die


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)