C 또는 Python에서 Popen을 사용한 하위 프로세스 출력의 버퍼링 우회

StackOverflow https://stackoverflow.com/questions/1410849

  •  05-07-2019
  •  | 
  •  

문제

Python 스크립트 또는 일부 C 코드를 작성하고 콘솔 (Win 또는 Linux)에서 결과 실행 가능을 실행할 때 모든 운영 체제에 적용되는 Popen (및 모든 관련 기능)에 대한 일반적인 질문이 있습니다. 출력을 즉시 볼 수 있습니다. 과정에서. 그러나 STDOUT가 파이프로 리디렉션 된 상태에서 포크 프로세스와 동일한 실행 파일을 실행하면 출력 버퍼는 어딘가에, 일반적으로 부모 프로세스가 읽을 수있는 파이프에 기록되기 전에 최대 4096 바이트까지.

다음 Python 스크립트는 1024 바이트의 청크에서 출력을 생성합니다.

import os, sys, time

if __name__ == "__main__":
     dye = '@'*1024
     for i in range (0,8):
        print dye
        time.sleep(1)

다음 Python 스크립트는 이전 스크립트를 실행하고 바이트 바이트 바이트 바이트가 되 자마자 출력을 읽습니다.

import os, sys, subprocess, time, thread

if __name__ == "__main__":
    execArgs = ["c:\\python25\\python.exe", "C:\\Scripts\\PythonScratch\\byte_stream.py"]

    p = subprocess.Popen(execArgs, bufsize=0, stdout=subprocess.PIPE)
    while p.returncode == None:
        data = p.stdout.read(1)
        sys.stdout.write(data)
        p.poll()

운영 체제의 경로를 조정하십시오. 이 구성에서 실행되면, Popen 명령의 버퍼 크기가 0으로 설정 되었음에도 불구하고 출력은 1024의 청크가 아니라 4096의 덩어리로 나타납니다 (어쨌든 기본값). 누구 든지이 행동을 바꾸는 방법을 말해 줄 수 있습니까? 버퍼링없이?

도움이 되었습니까?

해결책

일반적으로 표준 C 런타임 라이브러리 (모든 시스템의 거의 모든 프로그램을 대신하여 실행되는 것은 STDOut이 터미널인지 아닌지를 감지합니다. 그렇지 않은 경우 출력을 완충합니다 (이는 부패하지 않은 출력과 비교하여 효율성이 큰 승리).

글쓰기를하는 프로그램을 제어하고 있다면 (또 다른 답변이 제안한대로) Stdout을 지속적으로 플러시 할 수 있습니다. -u 명령 선 플래그 :

-u     : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)
         see man page for details on internal buffering relating to '-u'

(Man Page가 추가하는 것은 stdin 및 이진 모드의 문제 [s]에 대한 언급입니다).

글을 쓰고있는 프로그램을 만질 수 없거나 접촉하고 싶지 않다면 -u 또는 단지 독서하는 프로그램의 비슷한 것은 도움이되지 않을 것입니다 (가장 중요한 버퍼링은 독자의 stdin에있는 것이 아니라 작가의 stdout에서 일어나는 것입니다). 대안은 작가가 터미널에 글을 쓰고 있다고 믿도록하는 것입니다 (실제로 다른 프로그램에 글을 쓰고 있지만) pty 표준 라이브러리 모듈 또는 고급 제 3 자 pexpect 모듈 (또는 Windows의 경우 포트 초자마).

다른 팁

정확하고 Windows 및 Linux (및 기타 시스템) 모두에 적용됩니다. popen() 그리고 fopen(). 4096 바이트 전에 출력 버퍼를 발송하려면 사용하십시오. fflush() (C) 또는 sys.stdout.flush() (파이썬).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top