[PYTHON] 하위 프로세스 readline이 EOF를 기다리는 동안 중단됩니다.
PYTHON하위 프로세스 readline이 EOF를 기다리는 동안 중단됩니다.
파이썬 스크립트를 통해 실행하려고하는 간단한 C ++ 프로그램이 있습니다. (필자는 스크립트 작성에 익숙하지 않습니다.) 파이프를 통해 출력을 읽는 데 문제가 있습니다. 내가 본 것에서 보면 EOF가 없으면 readline ()이 작동하지 않는 것처럼 보이지만 프로그램 중간에서 읽고 스크립트가 출력되는 내용에 응답 할 수 있기를 원합니다. 출력을 읽는 대신, 그냥 멈 춥니 다. 파이썬 스크립트 :
#!/usr/bin/env python
import subprocess
def callRandomNumber():
print "Running the random guesser"
rng=subprocess.Popen("./randomNumber", stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
i=50
rng.stdin.write("%d\n" % i)
output=rng.stdout.readline()
output=rng.stdout.readline()
callRandomNumber()
1에서 100 사이의 임의의 숫자를 생성하는 c ++ 파일은 사용자가 올바르게 추측 할 때까지 추측을 확인합니다
#include<iostream>
#include<cstdlib>
using namespace std;
int main(){
cout<<"This program generates a random number from 1 to 100 and asks the user to enter guesses until they succuessfully guess the number. It then tells the user how many guesses it took them"<<endl;
srand(time(NULL));
int num=rand()%100;
int guessCount=0;
int guess=-1;
cout<<"Please enter a number: ";
cin>>guess;
while(guess!=num){
if(guess>num){cout<<"That guess is too high. Please guess again: ";}
else{cout<<"That guess is too low. Please guess again: ";}
cin>>guess;
guessCount++;
}
cout<<"Congratulations! You solved it in "<<guessCount<<" guesses!"<<endl;
return 0;
}
궁극적 인 목표는 스크립트가 이진 검색으로 문제를 해결하도록하는 것이지만, 지금은 단지 파일의 끝이 아닌 라인을 읽을 수 있기를 원합니다.
해결법
-
==============================
1.@Ron Reiter가 지적했듯이, cout은 newline을 암시 적으로 출력하지 않기 때문에 readline ()을 사용할 수 없습니다. std :: endl 또는 "\ n"이 필요합니다.
@Ron Reiter가 지적했듯이, cout은 newline을 암시 적으로 출력하지 않기 때문에 readline ()을 사용할 수 없습니다. std :: endl 또는 "\ n"이 필요합니다.
pexpect 모듈은 자식 프로그램을 변경할 수 없을 때 대화식으로 사용할 수있는 몇 가지 편리한 방법을 제공합니다 (일반적으로 터미널 / stdout 외부에서 직접 / 입출력을 처리하고 블록 버퍼링 문제는 무료입니다). ) :
#!/usr/bin/env python import sys if sys.version_info[:1] < (3,): from pexpect import spawn, EOF # $ pip install pexpect else: from pexpect import spawnu as spawn, EOF # Python 3 child = spawn("./randomNumber") # run command child.delaybeforesend = 0 child.logfile_read = sys.stdout # print child output to stdout for debugging child.expect("enter a number: ") # read the first prompt lo, hi = 0, 100 while lo <= hi: mid = (lo + hi) // 2 child.sendline(str(mid)) # send number index = child.expect([": ", EOF]) # read prompt if index == 0: # got prompt prompt = child.before if "too high" in prompt: hi = mid - 1 # guess > num elif "too low" in prompt: lo = mid + 1 # guess < num elif index == 1: # EOF assert "Congratulations" in child.before child.close() break else: print('not found') child.terminate() sys.exit(-child.signalstatus if child.signalstatus else child.exitstatus)
그것은 작동하지만 바이너리 검색이므로 (전통적으로) 버그가있을 수 있습니다.
다음은 비교를 위해 서브 프로세스 모듈을 사용하는 유사한 코드입니다.
#!/usr/bin/env python from __future__ import print_function import sys from subprocess import Popen, PIPE p = Popen("./randomNumber", stdin=PIPE, stdout=PIPE, bufsize=1, # line-buffering universal_newlines=True) # enable text mode p.stdout.readline() # discard welcome message: "This program gener... readchar = lambda: p.stdout.read(1) def read_until(char): buf = [] for c in iter(readchar, char): if not c: # EOF break buf.append(c) else: # no EOF buf.append(char) return ''.join(buf).strip() prompt = read_until(':') # read 1st prompt lo, hi = 0, 100 while lo <= hi: mid = (lo + hi) // 2 print(prompt, mid) print(mid, file=p.stdin) # send number prompt = read_until(':') # read prompt if "Congratulations" in prompt: print(prompt) print(mid) break # found elif "too high" in prompt: hi = mid - 1 # guess > num elif "too low" in prompt: lo = mid + 1 # guess < num else: print('not found') p.kill() for pipe in [p.stdin, p.stdout]: try: pipe.close() except OSError: pass sys.exit(p.wait())
-
==============================
2.나는 당신의 C ++ 프로그램에서 개행 문자를 추가하면 readline이 돌아 가게 될 것이라고 확신한다.
나는 당신의 C ++ 프로그램에서 개행 문자를 추가하면 readline이 돌아 가게 될 것이라고 확신한다.
-
==============================
3.명시 적으로 closestdin을해야 할 수도 있습니다. 따라서 자식 프로세스가 멈추는 것을 멈출 것입니다. 이는 코드에서 일어나는 현상입니다. 터미널에서 맨 위를 실행하고 random number의 상태가 수면 상태를 유지하는지 확인하고 0을 사용하는 경우 확인할 수 있습니다. 실행에 예상되는 시간이 지난 후 % CPU.
명시 적으로 closestdin을해야 할 수도 있습니다. 따라서 자식 프로세스가 멈추는 것을 멈출 것입니다. 이는 코드에서 일어나는 현상입니다. 터미널에서 맨 위를 실행하고 random number의 상태가 수면 상태를 유지하는지 확인하고 0을 사용하는 경우 확인할 수 있습니다. 실행에 예상되는 시간이 지난 후 % CPU.
즉, rng = subprocess (...) 호출 바로 다음에 rng.stdin.close ()를 추가하면 아무 문제없이 재개 될 수 있습니다. 또 다른 옵션은 output = rng.communicate (stdin = "% d \ n"% i)이고 stdout과 stderr 인 output [0]과 output [1]을 각각 보는 것입니다. 여기서 정보를 찾을 수 있습니다.
from https://stackoverflow.com/questions/7897202/subprocess-readline-hangs-waiting-for-eof by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] Tkinter 위젯이 None으로 저장된 이유는 무엇입니까? (AttributeError : 'NoneType'객체 ...) (TypeError : 'NoneType'객체 ...) [duplicate] (0) | 2018.10.05 |
---|---|
[PYTHON] Jinja로 JS로 렌더링하면 문자열이 아닌 숫자가 잘못 생성됩니다. (0) | 2018.10.05 |
[PYTHON] 32 비트 Windows 7 머신에서 Python 3.5에 scipy 설치 (0) | 2018.10.05 |
[PYTHON] SQLAlchemy에서 튜플 대신 속성 목록 쿼리 (0) | 2018.10.05 |
[PYTHON] 싱글 톤을 정의하는 간단하고 우아한 방법이 있습니까? [복제] (0) | 2018.10.05 |