2016-08-28 6 views
2

나는 서브 프로세스 모듈 섹션에서는 popen 클래스에 파이썬 문서를 읽고, 그리고 난 다음 코드를 통해 온 :파이썬 하위 프로세스가 SIGPIPE를 얻는 조건은 무엇입니까?

p1 = Popen(["dmesg"], stdout=PIPE) 
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) 
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits. 
output = p2.communicate()[0] 

documentation는 또한

는 "p1.stdout을 말한다. P1은 P1 전에 P2 종료 만약 SIGPIPE를받을 수의 (P2)를 시작한 후 close()를 호출 순서대로 중요합니다.

우리가 SIGPIPE의가 나타난다 전에 p1.stdout이 닫혀 있어야하는 이유

d p1은 우리가 이미 그것을 닫으면 p2가 p1 전에 존재한다는 것을 어떻게 알 수 있습니까?

답변

4

SIGPIPEdmesg이 닫힌 파이프에 쓰려고 할 때 보내지는 신호입니다. 여기에서 dmesg두 개의 대상으로 끝나고 파이썬 프로세스와 grep 프로세스로 끝납니다.

subprocess 클론 파일 핸들 (os.dup2() function 사용) 때문입니다. p2p1.stdout을 사용하도록 구성하면 OS가 파이프 파일 핸들을 복제하도록 요청하는 os.dup2() 호출이 트리거됩니다. 중복은 dmesggrep에 연결하는 데 사용됩니다. 두 오픈 파일

는 그 중 하나의 너무 grep 폐쇄가 검출되지 않을 것이고, 초기 닫으면 dmesg 표준 출력 들면 dmesgSIGPIPE 신호를주지 않는다 처리한다. dmesg은 불필요하게 출력을 계속 생성합니다.

그래서 즉시 p1.stdout을 닫아, 당신은 dmesg 표준 출력에서 ​​읽기 유일하게 남아있는 파일 핸들이 grep 과정이며, 그 프로세스가 종료한다면, dmesgSIGPIPE를받을 수 있도록.

+0

@MartijnPieters 왜'p1'이 여전히 stdout에 쓰고 있습니까? 파이썬이 진정으로'dup2 (p1.stdout, PIPE)'를 호출한다면,'p1'은 어디서든 stdout에 쓰기를해서는 안된다는 것을 의미합니다. 파이프가 p2의 끝에서 닫히면 적절한 SIGPIPE를 보냅니다. 또는 파이썬은 실제로 dup2를 호출하지 않지만 stdout이 기록 될 때 쓰는 다른 파일 설명자를 작성합니다. – darksky

+0

@darksky : 파이썬은'dup2 (p1.stdout.fileno(), 0)를 여기 호출하여 자식 프로세스의 stdin을 파이프 파일 번호로 대체합니다. 왜 이것은'p1이 stdout에 어떤 글을 써서는 안된다는 뜻인가? 'p1.stdout'은 파이프 **의 한쪽 끝이고,'p1'은 다른 쪽 끝에 쓰고 있습니다. 'p1.stdout'은 파이프의 수신 측에 대한 파이썬 프로세스 참조 일뿐입니다. –

+0

@darksky : 파이썬은'dup2 (p1.stdout.fileno(), 0)'를 여기 호출하여 하위 프로세스의 stdin을 파이프 파일 번호로 대체합니다. 왜 이것은'p1이 stdout에 어떤 글을 써서는 안된다는 뜻인가? 'p1.stdout'은 파이프 **의 한쪽 끝이고,'p1'은 다른 쪽 끝에 쓰고 있습니다. 'p1.stdout'은 파이프의 수신 측에 대한 파이썬 프로세스 참조 일뿐입니다. –

관련 문제