System ()로 백그라운드에서 시작된 어린이 프로세스를 기다릴 수있는 방법은 무엇입니까?

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

문제

여러 매개 변수에 대한 쉘 스크립트를 실행하는 Perl 코드가있어서 단순화하기 위해 다음과 같은 코드가 있다고 가정합니다.

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

그 후 더 많은 일을하고 싶지만 계속하기 전에 모든 어린이 과정이 끝날 때까지 기다릴 수있는 방법을 찾을 수는 없습니다.

코드를 Fork () 사용하도록 변환하는 것은 어려울 것입니다. 더 쉬운 방법이 없습니까?

도움이 되었습니까?

해결책

포크/exec/대기 사용은 그렇게 나쁘지 않습니다.

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

다른 팁

당신은 무언가를 변경해야하고, 포크를 사용하도록 코드를 변경해야 할 것입니다. 그러나 포크 사용에 대해 죽은 세트 인 경우 파일이 완료 될 때 파일을 터치하는 래퍼 쉘 스크립트를 사용할 수 있습니다. 파일의 존재를 확인하십시오.

래퍼는 다음과 같습니다.

#!/bin/bash

$*

touch /tmp/$2.$PPID

Perl 코드는 다음과 같습니다.

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

그러나 나는 포킹 코드가 더 안전하고 명확하다고 생각합니다.

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

포크 ()로 변환하는 것은 어려울 수 있지만 올바른 도구입니다. System ()은 차단 호출입니다. 쉘을 실행하고 스크립트를 백그라운드에서 실행하도록 지시함으로써 비 블로킹 동작을 받고 있습니다. 즉, Perl은 아이들의 PID가 무엇인지 전혀 모른다는 것을 의미합니다. 즉, 대본이 무엇을 기다릴지 모릅니다.

PIDS를 PERL 스크립트까지 통신하려고 시도 할 수 있지만 빠르게 손을 떼십시오. 포크 ()를 사용하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top