Frage

ich einige Perl-Code haben, der ein Shell-Skript für mehrere Parameter ausgeführt wird, zu vereinfachen, werde ich einfach mal davon aus, dass ich Code haben, der wie folgt aussieht:

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

Ich möchte einige Dinge mehr nach, das zu tun, aber ich kann nicht einen Weg finden, zu warten, für alle Prozesse Kind, bevor Sie fortfahren zu beenden.

Sie den Code konvertieren verwenden fork () wäre schwierig. Gibt es nicht einen einfacheren Weg?

War es hilfreich?

Lösung

Mit fork / exec / Wartezeit ist nicht so schlecht:

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";

Andere Tipps

Sie gehen zu müssen, etwas ändern, den Code zu ändern Gabel zu verwenden, sind wahrscheinlich einfacher, aber wenn Sie absolut gegen mit Gabel sind, könnten Sie einen Wrapper-Shell-Skript verwenden, das eine Datei berührt, wenn es fertig ist und dann hat Ihre Perl-Code Prüfung für die Existenz der Dateien.

Hier ist der Wrapper:

#!/bin/bash

$*

touch /tmp/$2.$PPID

Ihr Perl-Code würde wie folgt aussehen:

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

Aber ich denke, das Forking Code ist sicherer und klarer:

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;
}

Die Umstellung auf fork () könnte schwierig sein, aber es ist das richtige Werkzeug. System () ist ein blockierende Anruf; Sie bekommen das nicht-blockierende Verhalten durch eine Shell ausführen und sagen, es Ihre Scripts im Hintergrund laufen zu lassen. Das bedeutet, dass Perl keine Ahnung hat, was die PIDs der Kinder auch sein mag, was bedeutet, dass das Skript nicht weiß, was zu warten.

Sie könnten versuchen, die PIDs bis zu dem Perl-Skript zu kommunizieren, aber das wird schnell aus der Hand. Verwenden Sie fork ().

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top