파이프에서 실행될 때 하위 프로세스를 시작하는 프로그램의 동작을 이해하려고 합니다.
이 bash 프로그램 fork.sh는 즉시 다음을 인쇄하고 반환합니다.
(sleep 1) &
echo 'here'
하지만 파이프에 연결하면 읽기 측이 수면이 완료될 때까지 기다리는 것처럼 보입니다.
$ time bash fork.sh | wc
1 1 5
real 0m1.014s
나는 또한 이것을 Ruby에서 시도했고 수면 차단을 방지하기 위해 몇 가지 추가 호출을 수행했습니다.
Process.detach(fork { sleep 1 })
puts 'here'
fork {
sleep 1
Process.daemon
}
puts 'here'
하지만 그들의 행동은 똑같습니다.
이 문제(Unix, 파일 설명자 등의 측면에서)의 원인이 무엇인지, 그리고 파이프가 1초 내에 반환되도록 이들 중 하나를 재정의할 수 있는 방법이 있는지 알고 싶습니다.
편집: 아래 답변은 Ruby 예제의 문제점을 파악하는 데 도움이 되었습니다. 호출이 daemon()
먼저 이루어져야 합니다. 나는 그것이 어떤 방식으로든 전체 과정에 적용된다고 생각했을 것이다.
답변1
- 하위 프로세스는 상위 프로세스로부터 모든 파일 설명자를 상속받습니다.
- 명령을 실행할 때(
sleep
여기서는 쉘에 내장 명령이 없다고 가정)실행 시 닫기플래그는 꺼져 있지만 쉘은 이를 stdout(fd 1)에 설정하지 않습니다. - 관로리더다음과 같은 경우에만 EOF를 얻을 수 있습니다.모두쓰기 끝을 가리키는 파일 설명자가 닫혔습니다.
time bash fork.sh | wc
sleep
프로세스가 시작부터 읽고 있는 파이프의 쓰기 끝을 fork.sh
가리키는 표준 출력을 삭제 하도록 해야 합니다 .wc
fork.sh
(sleep 1 >/dev/null) &
echo 'here'
이 경우 sleep .. >&-
(다른 곳으로 리디렉션하지 않고 stdout을 닫는 것)도 작동하지만 프로세스가 일부 파일을 열면 반환된 파일 설명자가 1 = std 출력이 되어 가정을 깨뜨릴 수 있으므로 일반적으로 권장하지 않습니다. 오류를 유발합니다.