2010-12-05 5 views
2

많은 데이터를 뒤섞기위한 스크립트를 작성 중입니다. 문서 내가 (주석 참조) outproc를 기다릴 때, 비록 내가 교착 상태를 치는거야, 경고로Python : 교착 상태없이 데이터를 스트림하기 위해 서브 프로세스 사용?

outproc = None 
for input in input_files: 
    p = Popen('process_input "%s" | more_input_processing' %(input,), 
       shell=True, stdout=PIPE) 
    for line in p.stdout.xreadlines(): 
     if linecount % 1000000 == 0: 
      outfile = "output%03d" %(linecount // 1000000,) 
      if outproc: 
       outproc.stdin.close() 
       result = outproc.wait() # <-- deadlock here 
       assert result == 0, "outproc exited with %s" %(result,) 
      outproc = Popen('handle_output "%s"' %(outfile,), 
          shell=True, stdin=PIPE) 
     linecount += 1 
     outproc.stdin.write(line) 
    p.stdout.close() 
    result = p.wait() 
    assert result == 0, "p exited with %s" %(result,) 

: 그것은이 같은입니다.

설명서에서 제안한 "솔루션"은 .communicate()을 사용하는 것입니다.하지만 이렇게하면 플러시하기 전에 모든 입력을 메모리로 읽어들이는 것이 바람직하지 않습니다.

그래서 어떻게 교착 상태없이 하위 프로세스간에 데이터를 스트리밍 할 수 있습니까?

+0

그래, 실제로 하위 프로세스를 기다리지 않으면 (즉,'.wait()'에 대한 모든 호출을 제거하면 모든 것이 제대로 작동하는 것처럼 보입니다.이 스크립트는 괜찮습니다.). 그래도 제대로 작동하는 방법을 알아낼 수 있다면 좋을 것입니다 ... –

답변

0

서브 프로세스가 실제로 읽는 파이프에서 close을 사용하지 않으므로 SIGPIPE 또는 종료를 유발하는 요소가 수신되지 않습니다. 충분한 데이터가있을 때 프로세스를 종료하십시오. 또는 입력과 출력을 모두 파이프하고 select를 사용하여 읽거나 쓰는 시간을 알 수 있습니다.

+0

"서브 프로세스가 읽는 파이프에서'close'를 사용하지 않는다는 것은 무엇을 의미합니까? 'handle_output' 스크립트는 지속적으로 stdin에서 읽습니다 ... 그래서'outproc.stdin.close()'를 호출하면 파이프를 닫지 않습니다. –

+0

하위 프로세스의 표준 입력은 프로세스가 자체적으로 연 파이프가 아닙니다. 그것은 커맨드 라인 args에서 파일을 열었고 당신을 대신해서 그것을 닫을 수 없다. – Tobu

+0

Hrm. 알았어 ...하지만 프로세스를 죽이는 것만으로는 충분하지 않습니다. stdin에서 읽기를 완료 한 후 (그리고 데이터베이스가 커밋되지 않으면) 데이터베이스 정리가 필요합니다. –

관련 문제