[Python3] 프로세스

Alexandria·2023년 8월 31일
0

Python3 Basic

목록 보기
19/19
post-thumbnail

1. Process

다양한 작업들을 병렬적으로 실행하기 위한 기본 단위입니다. Process는 운영체제에서 관리하는 독립적인 실행 단위로, 각각의 프로세스는 독립된 메모리 공간을 갖습니다.

Python에서 Process를 사용하기 위해서는 multiprocessing 모듈을 사용합니다. multiprocessing 모듈은 threading 모듈과 비슷하지만, 여러 CPU를 활용해 병렬적으로 처리할 수 있도록 설계되어 있습니다.

다음과 같이 수행할 함수 명과 인자를 전달하여 생성합니다. 이후 start()를 호출하여 자식 프로세스에게 주어진 일을 수행하게 합니다.

join()은 자식 프로세스가 종료될 때까지 메인 프로세스의 종료를 방지합니다.

import multiprocessing

def work(start:int, end:int):
    _   = 0
    for i in range(start, end):
        _ += i
    print(f"child process id : {multiprocessing.current_process().pid}")


if __name__ == "__main__":
    print(f"parent process id : {multiprocessing.current_process().pid}")
    process1    = multiprocessing.Process(target=work, args=(0, 10000))
    process1.start()
    process1.join()

기본적으로 메인 프로세스가 종료되더라도 자식 프로세스는 끝까지 동작하지만 메인 프로세스가 종료되면 하위 프로세스도 종료되게 가능합니다.

import multiprocessing

def work(start:int, end:int):
    _   = 0
    for i in range(start, end):
        _ += i


if __name__ == "__main__":
    process1    = multiprocessing.Process(target=work, args=(0, 10000))
    process1.daemon = True
    process1.start()

자식 프로세스가 수행할 함수의 인자가 한 개만 필요하더라도 다음과 같이 args에 쉼표는 유지하여야 합니다.

import multiprocessing

def work(end:int):
    _   = 0
    for i in range(end):
        _ += i


if __name__ == "__main__":
    process1    = multiprocessing.Process(target=work, args=(10000,))
    process1.start()
    process1.join()

2. Multi Process

2.1. Process

아래의 예제와 같이 프로세스를 여러개를 생성하여 병렬 처리를 할 수 있습니다.

운영체제와 하드웨어에 따라 프로세스의 개수가 한계가 존재하므로

과다하게 프로세스를 생성하면 운영체제가 멈출 수 있음을 유의합니다.

import os
import multiprocessing

def work(arg:int):
    print(f"pid : {os.getpid()}")
    print(f"arg : {arg}")

args = [i for i in range(5)]
processes = []

for arg in args:
    p = multiprocessing.Process(target=work, args=(arg,))
    processes.append(p)
    p.start()

for p in processes:
    p.join()

병렬처리를 이용할 때, 작업 함수의 결과가 필요할 수 있습니다. 이때는 Queue를 이용합니다.

put()을 이용하여 Queue에 데이터를 넣고, get()을 이용하여 Queue의 데이터를 가져올 수 있습니다.

아래의 예제는 0부터 5까지의 숫자중 짝수만 출력하는 함수를 병렬처리한 예제입니다.

import multiprocessing

def work(arg:int, queue:multiprocessing.Queue):
    if arg % 2 == 0:
        queue.put(arg)

args = [i for i in range(5)]
processes = []
queue = multiprocessing.Queue()

for arg in args:
    p = multiprocessing.Process(target=work, args=(arg, queue))
    processes.append(p)
    p.start()

for p in processes:
    p.join()

while not queue.empty():
    print(queue.get())

2.2. Pool

Pool은 병렬 처리를 위한 작업자 프로세스들을 관리하는 객체입니다. Pool의 processes인자를 통해 생성할 최대 프로세스 수를 지정할 수 있습니다.

import time
import os
import multiprocessing

def work(arg:int):
    time.sleep(1)
    print(f"pid : {os.getpid()}")
    if arg % 2 == 0:
        return arg

if __name__ == "__main__":
    result = []

    with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
        result = [data for data in pool.map(work, [i for i in range(5)]) if data != None]

    print(result)

💡 multiprocessing.cpu_count()는 현재 시스템의 프로세서 갯수입니다. Pool의 processes는 프로세스를 생성하는 것이므로 프로세서의 갯수보다 많아도 동작합니다.

profile
IT 도서관

0개의 댓글