[Python] subprocess 모듈 에러, 교착상태(deadlock)

봉글렛·2023년 4월 24일
0

python

목록 보기
4/4

Subprocess란?

subprocess모듈은 파이썬 프로그램 내에서 새로운 프로세스를 생성하고 만들어진 프로세스를 파이프로 연결하여 리턴받을 수 있는 모듈입니다.

사용법에 대해서는 후에 다시 정리하고 오늘은 제가 경험한 에러에 대해서만 설명드리겠습니다.

error case

subprocess를 이용해 다른 파이썬스크립트를 돌리고 있었는데 정상적으로 돌던 와중에 멈추는 현상을 감지했습니다. 이 현상은 반복문에서 나타나는데 꼭 반복문이 특정 횟수 3~5회가 넘어가는 시점에 deadlock이 걸리는 현상이 있었습니다. 이 문제를 재연하기위한 테스트 코드를 작성해 보았습니다.

아래코드는 subprocess를 이용해 실행할 프로세스입니다.

# test.py
for i in range(10):
    print('############try: ', i)
    dsa = 1
    print('hello', dsa)
    a = ['text', 1, 2, 3]
    print(a*100)

실행시킬 스크립트

import os
import subprocess               

python_file = os.path.abspath('test.py')
cmd = ['python', python_file]

process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process.wait()
sys.stdout.write(po.stdout.read().decode())
sys.stderr.write(po.stderr.read().decode())

위에 코드처럼 돌리면 process.wait()이 부분에서 교착상태에 걸리게된다.
어느 부분에서 걸리는지 확인하려면 로그를 남기면 되는데 그 방법은 아래 링크의 방법을 사용하시면 실시간으로 확인 가능합니다.
python log 남기는법

해결

이제 에러는 재연 했으니 원인부터 간단하게 설명 드리자면 반복문(for, while)에 print()을 사용하면서 생기는 문제였습니다. 정확한 원인은 모르겠으나 출력값을 PIPE로 연결되면서 문제가 생긴듯 합니다.
방법은 두가지가 있습니다.

  • subprocess.Popen이 아닌 run을 사용한다
process = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
sys.stdout.write(process.stdout.decode())
sys.stdout.write(process.stderr.decode())
  • wait()대신 with와 communicate()사용하기
with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) as process:
    stdout, stderr = process.communicate()
    sys.stdout.write(stdout)
    sys.stdout.write(stderr)

참고
https://github.com/robotframework/robotframework/issues/4173

profile
어쩌다 개발자 (할 수 있을 때까지!!!!)

0개의 댓글