2016-07-16 4 views
1

(아마이 후 표준 입력을 닫아야합니다) 또한 내가 할 :Perl open2()와 함께 SIGCHLD, 교착 상태가 발생 했습니까? 나는 그것의 표준 입력을 통해 각 프로세스의 "매개 변수"를 전달 <code>IPC::Open2::open2()</code>와 여러 자식 프로세스를 열 FreeBSD의에 펄 스크립트에서

sub handle_SIGCHLD { 
    for(;;) { 
    my $kid = waitpid(-1, WNOHANG); 
    break if $kid == 0; 
    my $KidOutputFD = ...; # I stored the kid's output pipe FD earlier in the program 
    my $KidOutput = read_file($KidOutputFD); # use File::Slurp 
    # process $KidOutput 
    } 
}} 

$SIG{'CHLD'} = \&handle_SIGCHLD; 

지금 질문 : 이와 같은 코드에서 뭔가 교착 상태가 발생할 수 있습니까? 나는 아이가 도착했을 때가 아니라 아이의 결과물을 읽는 것을 더 선호한다. 문제가 발생할 수 있습니까?

또한 "stdin"을 통해 어린이에게 전달되는 매개 변수는 긴 문자열 일 수 있습니다. 전체 문자열을 하나의 print 연산자를 통해 자식 stdin의 FD와 함께 전달할 것입니다. 스크립트에 매개 변수를 작성하는 도중에 차단할 수 있습니까?

교착 상태가 발생하지 않도록하려면 어떻게해야합니까? 아마도 SIGPIPE를 처리해야합니까? (나는 그것을하고 싶지 않다. 입력 문자열을 자식 프로세스에 의해 출력 문자열로 간단하게 변환하기에는 너무 많은 작업이 필요하다. 더 간단한 방법이 있는가?)

또한 여러 자식 프로세스에 걸쳐있다. 때로는 프로세스가 종료 될 때까지 기다리는 경우가 있습니다. 때로는 SIGTERM을 사용하여 하위 프로세스를 종료합니다.


더 구체적인 질문 : (양면에서 열리고 폐쇄하지 않을) (상대방이 그것을 읽을 수없는 경우) 블록을 파이프에 기록 할 수 있습니까?

+1

'waitpid'는 -1을 반환 할 수 있으므로이 코드를 무한 루프에 넣을 수 있습니다. – mob

답변

0

http://man7.org/linux/man-pages/man7/pipe.7.html (FreeBSD가 아니지만, 이것은 중요하지 않다고 생각하며, 결국 OS가 변경 될 가능성이 있습니다.)

파이프 용량 파이프의 용량은 제한되어 있습니다. 파이프가 가득 차면 O_NONBLOCK 플래그가 설정되었는지 여부에 따라 write (2)가 차단되거나 실패합니다 (아래 참조).

따라서 자식 프로세스가 우리에게 데이터를 쓰려고 시도 할 수 있으며 dealock이 끝나면 무한히 기다릴 수 있습니다.

1

PIPE (양쪽에서 열리고 닫히지 않을 것입니다) 블록에 글을 쓸 수 있습니다 (다른 쪽에서 읽지 않는 경우)?

가장 확실합니다. 파이프는 유한 용량을 가지며 파이프가 꽉 차면 파이프에 쓰기가 차단됩니다.

예를 들어, 다음은 자녀에 발생할 수 :

  1. 는 STDOUT에 기록
  2. 가 STDOUT에 STDOUT에 쓸 수있는
  3. 시도 횟수를 기록 ... STDOUT
  4. 에 기록 , 파이프가 가득 차서 파이프가 비게 될 때까지 막습니다.

이렇게하면 자식이 종료 될 때까지 부모가 파이프에서 읽지 않기 때문에 자식이 무기한 차단됩니다 (따라서 종료되지 않습니다). 학부모가 원하는대로 자유롭게 할 수 있기 때문에 이것은 기술적으로 deadlock이 아니지만 확실히 문제입니다.

참고 : 자식이 핸들을 비 블로킹으로 만들면 블로킹 대신 쓰기가 실패합니다.