Domanda

Ho qualche codice Perl che esegue uno script di shell per più parametri, per semplificare, mi limiterò a supporre che Ho codice che assomiglia a questo:

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

Mi piacerebbe fare alcune cose dopo, ma non riesco a trovare un modo per attendere che tutti i processi figlio per terminare prima di continuare.

Conversione del codice da usare fork () sarebbe difficile. Non c'è un modo più semplice?

È stato utile?

Soluzione

utilizzando fork / exec / attesa non è poi così male:

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

Altri suggerimenti

Si sta andando ad avere per cambiare qualcosa, cambiare il codice per utilizzare la forcella è probabilmente più semplice, ma se si è assolutamente contrario utilizzando fork, è possibile utilizzare uno script di shell wrapper che tocca un file quando viene fatto e quindi avere il vostro controllo codice Perl per l'esistenza dei file.

Ecco l'involucro:

#!/bin/bash

$*

touch /tmp/$2.$PPID

Il tuo codice Perl sarà simile:

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

Ma penso che il codice di biforcazione è più sicuro e più chiara:

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

Conversione fork () potrebbe essere difficile, ma è lo strumento corretto. Sistema () è una chiamata di blocco; che stai ricevendo il comportamento non-blocking eseguendo una shell e dicendogli di eseguire i propri script in background. Ciò significa che Perl non ha idea di quali possano essere i PID dei bambini, il che significa che lo script non sa cosa aspettare.

Si potrebbe provare a comunicare il PID fino allo script Perl, ma che diventa rapidamente di mano. Usare fork ().

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top