2013-06-19 1 views
3

지금 당장이 문제가 발생하고 해결책을 찾을 수없는 것 같습니다. subprocess.Popen()을 사용하여 나를 위해 무거운 계산을 수행하는 C++ 응용 프로그램이지만 Popen()에서 멈추는 경우 stdout.read(); 여기 파이썬 코드입니다 :하위 프로세스가 popen()을 멈 춥니 다. stdout.read

process = subprocess.Popen(['/path/to/my/executable'], shell=False, 
stdout=subprocess.PIPE, stdin=subprocess.PIPE) 
process.stdin.write("Some String") 
print process.stdout.read()#It freezes here 

여기에 C++ 코드입니다 :

int main(int argc, char** argv) { 
    ...Prep work... 
    while (1) { 
     string input; 
     cin>>input; 
    ...Some Work ... 
     cout<< response; 
    } 
} 

는 C++ 코드는 쉘에서 완벽하게 작동하지만, 파이썬에 얼어 이유를 알아낼 수 없습니다

+0

파이썬 스크립트가 서브 프로세스가 끝날 때까지 대기하기 때문에? –

+0

프로세스를 끝내기를 기다리지 않고 해당 한 장을 읽을 수 있습니까? –

+0

'process.stdin'가 버퍼링되면, 당신의 쓰기가 C++ 프로그램에 즉시 보이지 않을 수도 있습니다. 마찬가지로,'process.stdout'가 버퍼링된다면, C++ 쓰기는 파이썬 프로그램에 즉시 보이지 않을 수도 있습니다. – chepner

답변

3

대신 communicate()을 사용하십시오.

import subprocess 
process = subprocess.Popen(['app'], shell=False, 
          stdout=subprocess.PIPE, 
          stdin=subprocess.PIPE) 
out, err = process.communicate("Some String") 
print out 

또한 요 어떤 시점에서 C++ 프로세스를 종료합니다. 당신이 당신의 입력 스트림의 끝에 도달 할 때 예를 들어, :

#include <string> 
#include <iostream> 
using namespace std; 

int main(int argc, char** argv) { 
    //...Prep work... 
    while (cin) { // <-- Will eventually reach the end of the input stream 
     string input; 
     cin >> input; 
     //...Some Work ... 
     string response = input; 
     cout << response; 
    } 
} 

파이썬의 문서에서이에 대한 경고가있다 : http://docs.python.org/2/library/subprocess.html#subprocess.Popen.stdin (오른쪽 위)

그것은 설명 당신은 외부 응용 프로그램을 작성할 때 , 데이터는 큐에 넣을 수 있습니다. 또한 외부 앱의 출력도 대기열에 저장됩니다. communicate()는 외부 앱으로 보내는 콘텐츠를 "플러시"하고 앱이 종료 될 때까지 기다립니다.

communicate()을 사용하면 전체 외부 앱의 출력이 메모리에 저장됩니다. 실용적이지 않은 경우 (예 : 거대한 출력), stdin 및 stdout 객체를 사용하여 쓰거나 읽을 수 있습니다. 당신은 "교착 상태"하지 돌봐해야합니다 :

import subprocess 

process = subprocess.Popen(['app'], shell=False, 
          stdout=subprocess.PIPE, 
          stdin=subprocess.PIPE) 
process.stdin.write("Some String") 
process.stdin.close() # <-- Makes sure the external app gets an EOF while 
         #  reading its input stream. 
for line in process.stdout.readlines(): 
    print line 

그러나 심지어이 기술을 사용하면 외부 응용 프로그램에 제공 입력이 쓰는 동안 막지 않도록 할 수있을만큼 작은 크기인지 확인합니다.

입력이 너무 큰 경우 읽기 및 쓰기가 차단되지 않도록해야합니다. 스레드를 사용하는 것이 가장 좋은 선택입니다.

+0

답장을 보내 주셔서 감사합니다. @Teebrin, 지금 시도해 보았습니다. 이 오류가 발생합니다. err = process.communicate (명령) 파일 "/usr/lib/python2.7/subprocess".py ", 줄 806, 통신 있음 return self._communicate (입력) 파일"/usr/lib/python2.7/subprocess.py ", 줄 1382, _communicate에 stdout, stderr = self._communicate_with_poll (입력) 파일 "/usr/lib/python2.7/subprocess.py", 1456 줄, _communicate_with_poll에 데이터 = os.read (fd, 4096) MemoryError –

+0

외부 응용 프로그램에서 방대한 양의 데이터를 출력하고있을 가능성이 있습니다. 대답을 통해 거대한 출력물을 읽는 방법을 보여줄 수 있습니다. 사실, 원래 코드를 조금 더 닮았습니다. – Teebrin

0

일반적으로 우리는 더 이상 데이터까지 모든 답장을 읽은 다음 2) 서브 프로세스에 무언가를 방출) 1 IO, 비 블록 1-2 사용하여 스레드도 도움이 될 것입니다 반복해야합니다.

관련 문제