>백엔드 개발 >파이썬 튜토리얼 >`for line in iter(process.stdout.readline, \'\')`를 사용하여 C 프로그램에서 출력을 읽을 때 Python `subprocess`가 중단되는 이유는 무엇입니까?

`for line in iter(process.stdout.readline, \'\')`를 사용하여 C 프로그램에서 출력을 읽을 때 Python `subprocess`가 중단되는 이유는 무엇입니까?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-11-18 05:23:02734검색

Why Does My Python `subprocess` Hang When Reading Output from a C Program Using `for line in iter(process.stdout.readline, '')`?

Python 하위 프로세스가 "for line in iter"로 인해 중단됩니다.

이 시나리오에서 Python 스크립트는 C 프로그램을 실행하고 데이터를 수신하기 위한 것입니다. 그 출력. 그런데 스크립트가 "for line in iter(process.stdout.readline, '')" 줄에서 멈춥니다.

버퍼링 문제

문제는 다음에서 발생합니다. 버퍼링 문제. C 프로그램에서 stdout은 일반적으로 출력이 파이프될 때 블록 버퍼링됩니다. 이는 특정 양이 기록되거나 개행 문자가 나타날 때까지 출력이 버퍼링된다는 의미입니다.

C 프로그램에서 while 루프의 각 반복은 "2000"을 인쇄하고 1초 동안 휴면합니다. 줄바꿈이 인쇄되지 않으므로 출력이 버퍼링됩니다.

For Line in Iter Issue

Python에서 subprocess.stdout.readline()은 자식의 stdout을 읽습니다. 처리하고 한 줄을 반환합니다. "iter()의 for line" 루프는 readline()이 반환한 라인을 반복합니다.

그러나 C 프로그램의 출력은 버퍼링으로 인해 플러시되지 않으므로 해당 지점에서 읽을 라인이 없습니다. 여기서 Python 스크립트가 루프에 들어갑니다. 따라서 스크립트는 이 줄에서 무기한 대기합니다.

솔루션

C 프로그램의 버퍼링 수정

  • setvbuf(): C 프로그램은 다음을 사용할 수 있습니다. setvbuf()는 stdout에 대한 라인 버퍼링을 강제합니다. 이렇게 하면 인쇄 후 각 줄이 즉시 플러시됩니다.
setvbuf(stdout, (char *) NULL, _IOLBF, 0);
  • stdbuf 유틸리티: stdbuf 유틸리티는 C 프로그램을 래핑하고 해당 내용을 변경하는 데 사용할 수 있습니다. 버퍼링 동작.
stdbuf -oL ./main

Pseudo-TTY

  • Pty 모듈: pty 모듈을 사용하여 C 프로그램이 대화형으로 실행되고 있다고 생각하도록 속이는 의사 TTY입니다. 이 모드에서 출력은 기본적으로 라인 버퍼링됩니다.
import pty
master_fd, slave_fd = pty.openpty()
process = Popen("./main", stdin=slave_fd, stdout=slave_fd, stderr=STDOUT,
                bufsize=0, close_fds=True)
  • pexpect 라이브러리: pexpect 라이브러리는 ptys 작업을 위한 상위 수준 인터페이스를 제공합니다.
import pexpect
child = pexpect.spawn("./main")
for line in child:
    print line

이러한 솔루션 중 하나를 적용하면 버퍼링 문제가 발생합니다. 해결되어 Python 스크립트가 C 프로그램의 출력을 예상대로 읽을 수 있게 되었습니다.

위 내용은 `for line in iter(process.stdout.readline, '')`를 사용하여 C 프로그램에서 출력을 읽을 때 Python `subprocess`가 중단되는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.