2010-02-03 12 views
3

필자는 자식 프로세스에서 백그라운드 프로그램을 fork하고 호출하는 Perl 프로그램을 작성했으며 부모 프로세스에서 몇 가지 작업을 수행하는 끝이없는 while 루프가 있습니다. 프로그램이 종료하기 전에 반환하지 않을 수 있도록Perl에서 백그라운드 프로세스가 종료 될 때 어떻게 알림을받을 수 있습니까?

$pid = fork(); 
if (!$pid) { 
    exec("program args"); 
} else { 
    while (1) { 
     # do something 

     # needs help: if program terminated, break 
    } 
} 

답변

3

음, fork은 부모 프로세스에게 자녀의 PID (코드에서 정중하게 검색)를 처리합니다. 이것은 정확하게 부모가 아이를 돌볼 수 있도록합니다.

종료 할 때 루프를 종료하려면 kill 0 $pid을 사용하여 자식이 아직 있는지 확인할 수 있습니다. perldoc -f kill을 참조하십시오.

+0

문제는 프로세스가 좀비가되어 명령이 여전히 true를 반환한다는 것입니다. –

+0

$ SIG {CHLD} = '무시'(다음 답변 참조)를 설정할 때 작동합니다. –

-1

것 같아요, 간부는()는 차단하지만, 내가 잘못 될 수있다 : 자식 프로세스에서 백그라운드 프로그램이 종료 될 때 이제 while 루프는 남아 있어야합니다.

+0

-1 아니요, 프로그램은 이전에'fork'를 사용합니다. 그래서 하나의 자식 프로세스 만'exec'을 사용할 것입니다. – sleske

2

자식 프로세스가 종료 될 때 부모 프로세스가 보내지는 CHLD 신호를 처리하는 신호 처리기가 있어야합니다. (perl에서의 신호 처리에 대한 자세한 내용은 perldoc perlipc을 참조하십시오.)

자식 프로세스를 얻기 위해 else 루프에서 다음과 같이 할 수 있습니다.

... 
} else { 
    $SIG{CHLD} = \&reaper 
} 

# hash to store exit status of child processes 
our %child;  
sub reaper { 
    my $x; 
    while (($x = waitpid(-1,WNOHANG)) >0) { 
     $child{$x} = $? >> 8; 
    } 
} 

또는 $SIG{CHLD}='IGNORE'을 설정하면 하위 프로세스가 좀비가되는 것에 대해 걱정하지 않아도됩니다.

+0

팁 주셔서 감사합니다. 나는 위의 팁과 그것을 결합했다. –

0

신청서에 따라 자녀가 끝나고 부모님이 수료 할 때 수시로 확인할 수 있습니다. posix waitpid()를 WNOHANG과 함께 사용하여 no-blocking 대기를 수행하거나 자식이 아직 실행 중인지 확인하는 신호를 보내거나 파이프를 사용할 수 있습니다 (닫을 때 확인). 개인적으로 나는 waitpid()를 사용할 것입니다. perlipc에 예제가있는 아주 좋은 설명이 있습니다.

관련 문제