Comment puis-je faire Perl attendre les processus enfants ont commencé en arrière-plan avec le système ()?

StackOverflow https://stackoverflow.com/questions/911520

Question

J'ai un code Perl qui exécute un script shell pour plusieurs paramètres, pour simplifier, je vais supposer que j'ai le code qui ressemble à ceci:

for $p (@a){
    system("/path/to/file.sh $p&");
}

Je voudrais faire quelques plus de choses après cela, mais je ne peux pas trouver un moyen d'attendre que tous les processus enfants pour terminer avant de poursuivre.

Conversion du code à utiliser fork () serait difficile. N'y at-il un moyen plus facile?

Était-ce utile?

La solution

En utilisant fork / exec / attente est pas si mal:

my @a = (1, 2, 3);
for my $p (@a) {
   my $pid = fork();
   if ($pid == -1) {
       die;
   } elsif ($pid == 0) {
      exec '/bin/sleep', $p or die;
   }
}
while (wait() != -1) {}
print "Done\n";

Autres conseils

Vous allez devoir changer quelque chose, de changer le code à utiliser la fourchette est probablement plus simple, mais si vous êtes absolument contre l'utilisation de fourche, vous pouvez utiliser un script shell wrapper qui touche un fichier lorsqu'il est fait et alors votre chèque de code Perl pour l'existence des fichiers.

Voici l'emballage:

#!/bin/bash

$*

touch /tmp/$2.$PPID

Votre code Perl ressemblerait à ceci:

for my $p (@a){
    system("/path/to/wrapper.sh /path/to/file.sh $p &");
}
while (@a) {
    delete $a[0] if -f "/tmp/$a[0].$$";
}

Mais je pense que le code de fork est plus sûr et plus clair:

my @pids;
for my $p (@a) {
    die "could not fork" unless defined(my $pid = fork);\
    unless ($pid) { #child execs
        exec "/path/to/file.sh", $p;
        die "exec of file.sh failed";
    }
    push @pids, $pid; #parent stores children's pids
}

#wait for all children to finish
for my $pid (@pids) {
    waitpid $pid, 0;
}

Conversion à la fourchette () peut être difficile, mais il est l'outil approprié. system () est un appel de blocage; vous obtenez le comportement non-bloquant en exécutant une coquille et lui disant d'exécuter vos scripts en arrière-plan. Cela signifie que Perl n'a aucune idée de ce que les enfants des PIDs pourraient être, ce qui signifie que votre script ne sait pas quoi attendre.

Vous pouvez essayer de communiquer jusqu'à l'PIDs le script Perl, mais qui devient rapidement la main. Utiliser fork ().

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top