Popen.communicate 이해
1st.pyREPL (read-eval-print-loop)을 생성 하는 스크립트가 있습니다 .
print "Something to print"
while True:
r = raw_input()
if r == 'n':
print "exiting"
break
else:
print "continuing"
그런 1st.py다음 다음 코드 로 시작했습니다 .
p = subprocess.Popen(["python","1st.py"], stdin=PIPE, stdout=PIPE)
그리고 이것을 시도했습니다.
print p.communicate()[0]
이 추적을 제공하여 실패했습니다.
Traceback (most recent call last):
File "1st.py", line 3, in <module>
r = raw_input()
EOFError: EOF when reading a line
여기서 무슨 일이 일어나고 있는지 설명해 주시겠습니까? 를 사용하면 p.stdout.read()영원히 멈 춥니 다.
.communicate() 입력을 쓰고 (이 경우에는 입력이 없으므로 하위 프로세스에 더 이상 입력이 없음을 알리기 위해 하위 프로세스의 stdin을 닫습니다) 모든 출력을 읽고 하위 프로세스가 종료 될 때까지 기다립니다.
EOFError 예외는 자식 프로세스에서 발생합니다 raw_input()(데이터를 예상했지만 EOF (데이터 없음)를 얻었습니다).
p.stdout.read()자식 이 교착 상태를 일으키는 입력 ( )을 기다리는 것과 동시에 자식의 모든 출력 을 읽으려고하기 때문에 영원히 중단됩니다 raw_input().
교착 상태를 방지하려면 비동기 적으로 (예 : 스레드 또는 선택을 사용하여) 읽기 / 쓰기를하거나 읽기 / 쓰기 시간과 양을 정확히 알아야합니다 . 예를 들면 다음과 같습니다.
from subprocess import PIPE, Popen
p = Popen(["python", "-u", "1st.py"], stdin=PIPE, stdout=PIPE, bufsize=1)
print p.stdout.readline(), # read the first line
for i in range(10): # repeat several times to show that it works
print >>p.stdin, i # write input
p.stdin.flush() # not necessary in this case
print p.stdout.readline(), # read output
print p.communicate("n\n")[0], # signal the child to exit,
# read the rest of the output,
# wait for the child to exit
참고 : 읽기 / 쓰기가 동기화되지 않으면 매우 취약한 코드입니다. 교착 상태입니다.
블록 버퍼링 문제에 주의하십시오 (여기서는 자식에서 stdin, stdout 에 대한 버퍼링을 해제하는 "-u"플래그를 사용하여 해결됨 ).
bufsize=1파이프를 부모 측에서 라인 버퍼링 합니다 .
통신 (input = "")을 사용하지 마십시오. 프로세스에 입력을 쓰고 stdin을 닫은 다음 모든 출력을 읽습니다.
다음과 같이하십시오.
p=subprocess.Popen(["python","1st.py"],stdin=PIPE,stdout=PIPE)
# get output from process "Something to print"
one_line_output = p.stdout.readline()
# write 'a line\n' to the process
p.stdin.write('a line\n')
# get output from process "not time to break"
one_line_output = p.stdout.readline()
# write "n\n" to that process for if r=='n':
p.stdin.write('n\n')
# read the last output from the process "Exiting"
one_line_output = p.stdout.readline()
오류를 제거하기 위해 수행 할 작업 :
all_the_process_will_tell_you = p.communicate('all you will ever say to this process\nn\n')[0]
But since communicate closes the stdout and stdin and stderr, you can not read or write after you called communicate.
Your second bit of code starts the first bit of code as a subprocess with piped input and output. It then closes its input and tries to read its output.
The first bit of code tries to read from standard input, but the process that started it closed its standard input, so it immediately reaches an end-of-file, which Python turns into an exception.
ReferenceURL : https://stackoverflow.com/questions/16768290/understanding-popen-communicate
'programing' 카테고리의 다른 글
| Setup () 대 SetupGet () (0) | 2021.01.15 |
|---|---|
| Python에서 구성 파일을 어디에 넣을까요? (0) | 2021.01.15 |
| ASP.NET MVC 4, HttpException을 throw하고 HttpStatusCodeResult를 반환합니까? (0) | 2021.01.15 |
| Maven 저장소에서 오래된 종속성을 정리하는 방법은 무엇입니까? (0) | 2021.01.15 |
| 부트 스트랩 3-점보트론 배경 이미지 효과 (0) | 2021.01.15 |