자식 프로세스를 생성하는 가장 간단한 방법은 fork()를 사용하는 것입니다. fork()는 파이썬 표준 라이브러리인 os 모듈에 포함된 함수로, 호출한 프로세스(부모)의 복제본인 새로운 프로세스(자식)를 만들어 줍니다.
이번 글에서는 여기에 pipe()를 함께 사용하여 부모 프로세스와 자식 프로세스 사이에 데이터를 전달하는 방법을 알아보겠습니다. 한 프로세스에서 다른 프로세스로 정보를 넘길 때는 pipe()가 활용됩니다.
파이프(pipe)의 특징
os.pipe()는 읽기용과 쓰기용 파일 디스크립터 두 개를 반환합니다. 중요한 점은 파이프가 단방향(unidirectional)이라는 것입니다. 즉, 한쪽 방향으로만 데이터를 흘려보낼 수 있습니다. 따라서 양방향 통신이 필요하다면 방향마다 하나씩, 총 두 개의 파이프를 열어야 합니다.
알고리즘
Step 1: 읽기(r)와 쓰기(w)에 사용할 파일 디스크립터를 생성한다.
Step 2: fork()를 호출하여 새로운 프로세스를 만든다.
Step 3: 프로세스 ID(pid)가 0이면 자식 프로세스이다.
Step 4: 그렇지 않으면 부모 프로세스이다.
예제 코드
import os
def parentchild(cwrites):
r, w = os.pipe()
pid = os.fork()
if pid:
os.close(w)
r = os.fdopen(r)
print ("Parent is reading")
str = r.read()
print( "Parent reads =", str)
else:
os.close(r)
w = os.fdopen(w, 'w')
print ("Child is writing")
w.write(cwrites)
print("Child writes = ",cwrites)
w.close()
# Driver code
cwrites = "Python Program"
parentchild(cwrites) 코드 설명
os.pipe()가 읽기 디스크립터r과 쓰기 디스크립터w를 반환합니다.os.fork()호출 후, 반환값인pid가 0이 아니면 부모 프로세스, 0이면 자식 프로세스로 분기합니다.- 부모 프로세스는 쓰기 끝(
w)을 닫고, 자식 프로세스는 읽기 끝(r)을 닫습니다. 사용하지 않는 파이프 끝을 닫아야 데이터 흐름이 정상적으로 종료됩니다. os.fdopen()으로 파일 디스크립터를 파일 객체로 감싸면 일반적인 파일 입출력처럼read(),write()를 사용할 수 있습니다.
실행 결과
Child is writing Child writes = Python Program Parent is reading Parent reads = Python Program
실행 결과를 보면 자식 프로세스가 먼저 "Python Program" 문자열을 파이프에 기록하고, 이어서 부모 프로세스가 같은 데이터를 읽어 출력하는 것을 확인할 수 있습니다. 이처럼 파이프는 관련 프로세스 간에 간단하고 효율적으로 데이터를 주고받을 수 있는 대표적인 IPC(프로세스 간 통신) 수단입니다.