[Python] 코드 병렬처리 (백그라운드 실행)

반응형

Python Logo

 

subprocess 라이브러리를 이용해 코드를 백그라운드로 실행하여 병렬 처리하는 방법을 알아보겠습니다.

 

Contents

     

    1. 배경

    회사에서 리눅스서버위에서 작업 스케쥴러와 함께 대규모 파이프라인을 돌리는 경우가 생겼습니다. 문제는 한 번 분석을 시작할 때, 분석 샘플들을 종류에 따라 나누어, 작업 스케쥴러를 돌려 병렬 처리할 스크립트가 달라진다는 점이었습니다. 즉, 분석 자동화 스크립트가 돌아갈 때, 샘플들을 종류별로 나누어, 파이프라인을 돌릴 쉘 스크립트들을 작업 스케쥴러에 병렬적으로 넣고, 한 샘플에 대해 여러 작업으로 나뉘어, 스크립트들이 큐에 쌓입니다. cfDNA 샘플은 샘플당 작업 큐에 쌓이는 스크립트만 100개가 넘고, PBMC 샘플은 30~40개 정도 됩니다. 한 배치에는 cfDNA가 80개 PBMC가 20개 정도 있습니다. 이렇게 많은 작업들이 모두 끝나면 그 결과를 읽어와 Post 분석까지 하는 스크립트를 만들어야 하는 게 해결할 문제였습니다. 즉, 샘플별로 작업 스케쥴러에 스크립트를 병렬적으로 넣고, 그 작업이 모두 끝날 때까지 기다리는 로직이 필요했습니다. subprocess 라이브러리의 sp.Popen을 이용해 해결하였고 그 과정을 정리하겠습니다.

     

    2. 핵심 로직 스크립트

    import subprocess as sp
    import sys
    
    # cmd가 작업 스케쥴러에 스크립트를 넣는 부분입니다.
    cmd="""
    import time
    import random
    k = random.randint(12,13)
    time.sleep(k)
    print(k)
    """
    
    nsum=0
    for i in range(300):
        globals()[f"a{i}"] = sp.Popen([sys.executable,'-c', cmd], stdout=sp.PIPE, stderr=sp.PIPE)
    print('병렬처리 진행중....')
    for i in range(300):
        exec(f"o,e = a{i}.communicate()")
        print(f"{int(o.decode('utf-8'))}시간")
        nsum+=int(o.decode('utf-8'))
    print(f"총 {nsum}시간 걸릴 일")

     

    1) 스크립트 설명

    실제론 cmd 부분에 서버의 작업 스케쥴러에 던질 스크립트를 실행하는 코드가 들어갑니다. 여기선 time 라이브러리에서 일정 시간을 대기하는 코드를 넣었습니다. 즉, 일정시간 걸리는 코드라고 보면 됩니다. random.randint(12,13)을 통해 약 12~13초 정도 걸린다고 해보겠습니다.

    이렇게 12~13초 걸리는 일을 300번 병렬처리 해보겠습니다. for i in range(300)을 통해 300번 작업 스케쥴러에 던졌다고 생각해봅니다.  cmd를 globals() 즉, 전역 환경의 a{i}에 넣고, 다시 300번 반복하며 a{i}.communicate()를 사용합니다. 실제로 하나당 12~13시간 걸리는 일이라고 상상해서, print("걸린 시간") 이런 식으로 프린트하게 했습니다. 

    코드를 돌려보면 12~13초 걸리는 작업 300개가 13초에 끝나는것을 볼 수 있습니다. 그 결과는 모두 o, e에 stdout과 stderr가 저장됩니다.

     

    2) 핵심 로직

    핵심 로직은 sp.Popen()을 통해 실행되는 cmd를 global 환경에 리스트로 저장하고, 해당 리스트를 반복하며 요소.communicate()를 o, e에 저장합니다. 이렇게 되면 순차적으로 병렬 처리를 할 수 있습니다.

     

     

    Reference)
    1. python logo: https://commons.wikimedia.org/wiki/File:Python_logo_and_wordmark.svg
    반응형

    댓글

    Designed by JB FACTORY