Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 개선 제안 한국어 번역

PEP 3145 – subprocess.Popen을 위한 비동기 I/O

Author:
Eric Pruitt, Charles R. McCreary, Josiah Carlson
Status:
Withdrawn
Type:
Standards Track
Created:
04-Aug-2009
Python-Version:
3.2
Post-History:


Table of Contents

번역·라이선스 안내

이 문서는 Open Publication License v1.0 이상에 따라 만든 수정된 한국어 번역본입니다. 수정자: yeokja/yeokja 프로젝트. 수정일: 2026-08-29. 변경 내용: 영어 원문을 한국어로 번역했습니다. 원저자와 저작권 표시는 위 Author 필드와 아래 Copyright 절에 유지했으며, 이 번역은 원저자의 승인이나 보증을 뜻하지 않습니다. 수정되지 않은 기준 원문 · 공식 최신판 · Open Publication License v1.0

초록

현재 형태의 subprocess.Popen 구현은 자식 프로세스의 데이터를 기다리는 동안 부모 Python 스크립트가 교착 상태에 빠지거나 블로킹되기 쉽습니다. 이 PEP는 이러한 문제를 완화하기 위해 subprocess.Popen을 더 비동기적으로 만들 것을 제안합니다.

PEP 보류

이 PEP에서 다루는 개념에 대한 추가 검토는 적어도 PEP 3156이 해결될 때까지 보류되었습니다.

PEP 철회

이 문제는 버그 트래커에서 다룰 수 있습니다. 구체적인 제안은 [11]에 첨부되어 있습니다.

동기

“python asynchronous subprocess”를 검색하면 자식 프로세스를 실행한 뒤 때때로 그 프로세스와 통신하고 싶어 하는 사람들의 사례를 수없이 찾을 수 있습니다. 이들은 프로그램이 데이터를 생성할 때까지 블로킹하며 기다리는 대신, 이미 읽을 수 있는 데이터만 읽기를 원합니다 [1] [2] [3]. 현재 subprocess 모듈의 동작에서는 사용자가 stdin, stderr, stdout 파일 객체를 통해 데이터를 보내거나 받을 때 교착 상태(dead lock, 잠금이 서로 얽히는 현상)가 흔히 발생하며, 이는 문서로도 기록되어 있습니다 [4] [5]. communicate를 사용하면 버퍼링 문제의 일부를 완화할 수 있습니다. 그러나 자식 프로세스에서 읽을 데이터가 없을 때 데이터를 읽으려고 하면 여전히 부모 프로세스가 블로킹됩니다.

근거

subprocess.Popen에 비동기 논블로킹 기능이 필요하다는 점은 여러 문서에서 확인할 수 있습니다 [6] [7] [2] [3]. 이 코드를 포함하면 Unix 기반 및 Windows 빌드의 Python에서 사용할 수 있는 Python 표준 라이브러리의 유용성이 향상됩니다. Python의 거의 모든 I/O 객체에는 어떤 형태로든 파일과 유사한 래퍼가 있습니다. 소켓은 이미 그렇게 동작하며, 문자열에는 StringIO가 있습니다. subprocess.Popen.stderr, stdout, stdin 파일류 객체에 붙어 있는 메서드를 사용하기만 하면 Popen을 파일처럼 동작하게 만들 수 있습니다. 그러나 이러한 객체의 read 및 write 메서드를 사용할 때는 비동기 I/O의 이점을 누릴 수 없습니다. 제안된 해결책에서는 래퍼가 비동기 메서드를 감싸서 파일 객체를 흉내 냅니다.

참조 구현

저는 테스트와 문서를 포함한 모든 변경 사항을 담은 Google Code 저장소 [9]와 개발 과정에서 마주친 문제를 자세히 설명하는 블로그 [10]를 관리해 왔습니다.

저는 subprocess 모듈에 논블로킹 비동기 I/O를 구현하는 작업을 해 왔습니다. 또한 subprocess.Popen용 래퍼 클래스도 구현해 왔습니다. 이 래퍼 클래스는 파일 객체의 모든 메서드와 속성을 복제하므로 실행된 프로세스가 파일을 대신할 수 있습니다.

subprocess.Popen 클래스에 추가된 기본 함수는 Popen.send와 Popen._recv 두 가지이며, 각각 Windows용과 Unix 기반 시스템용의 두 가지 별도 구현을 가지고 있습니다. Windows 구현은 kernel 32 DLL에서 파이프를 비동기 방식으로 제어하는 데 필요한 함수에 접근하기 위해 ctypes를 사용합니다. Unix 기반 시스템에서는 파일 제어를 위한 Python 인터페이스가 같은 역할을 합니다. Popen.send와 Popen._recv의 각 구현은 인자가 동일하므로, 이 함수들을 사용하는 코드는 여러 플랫폼에서 동작합니다.

Popen._recv 함수를 호출할 때는 파이프 이름을 인자로 전달해야 합니다. 그래서 기본적으로 stdout을 Popen._recv의 파이프로 선택하는 Popen.recv 함수가 있습니다. Popen.recv_err는 기본적으로 stderr를 파이프로 선택합니다. Popen.recv와 Popen.recv_err는 각각 Popen._recv('stdout' ...)와 Popen._recv('stderr' ...)보다 훨씬 읽고 이해하기 쉽습니다.

Popen._recv 함수는 값을 반환하기 전에 데이터가 생성되기를 기다리지 않으므로 빈 바이트를 반환할 수 있습니다. Popen.asyncread는 주어진 시간 간격 동안 읽은 데이터를 모두 반환하여 이 문제를 처리합니다.

ProcessIOWrapper 클래스는 asyncread와 asyncwrite 함수를 사용하여 프로세스가 파일처럼 동작하게 합니다. 따라서 subprocess.Popen 호출로 생성된 stdout 및 stdin 파일 객체를 사용할 때 생길 수 있는 블로킹 문제가 없습니다.

참고 문헌

[8] subprocess.rst - subprocdev - Project Hosting on Google Code https://web.archive.org/web/20130306074135/http://code.google.com/p/subprocdev/source/browse/doc/subprocess.rst?spec=svn2c925e935cad0166d5da85e37c742d8e7f609de5&r=2c925e935cad0166d5da85e37c742d8e7f609de5