Python

Python 문법 기초 35 - 멀티 thread(병렬구조)

코딩탕탕 2022. 10. 23. 13:56

 

파이썬에서는 멀티 thread가 불가능하다 GIL의 정책에 어긋나기 때문이다.

 

 

[Python] GIL (Global Interpreter Lock) 이해하기

이번 포스팅은 Python만의 특징 중 하나인 GIL(Global Interpreter Lock)의 개념에 대해 알아볼 것이다. Python 프로그래머라면 한 번쯤은 들어봤을 법한 용어지만, 정확하게 알고 있지 못한 분들도 많을 것

it-eldorado.tistory.com

파이썬은 병렬이 아닌 직렬 구조로서 병렬처럼 보이기 위해 눈속임을 하는 것 뿐이다. 완전한 병렬을 하기 위해서는 별도의 모듈을 받아야 한다.

 

 

병렬 구조(Pool, Process)

# GIL 정책에 의해 완전한 스레드 구현은 불가하다. 
# 그래서 multiprocessing 모듈로 GIL 정책을 우회하여 병렬처리가 가능하도록 하고 있다.

from multiprocessing import Pool, Process
import time
import os

# Pool : 입력 값에 대해 process들을 건너건너 분배하여 함수 실행을 병렬처리

def func(x):
    print('값 ', x, '에 대한 작업 process id : ', os.getpid())
    time.sleep(1)
    return x * x


print('\n---Process------------------')
def func2():
    print('연속적으로 어떤 작업을 진행')
    time.sleep(1)

def doubler(num):
    result = num + 10
    func2()
    proc = os.getpid()
    print('num:{0}, result:{1}, process id : {2}'.format(num, result, proc))
    

if __name__ == '__main__':
    startTime = int(time.time())
    
    """ 직렬 처리
    for i in range(0, 10):
        print(func(i)) 
    """
    
    # 병렬처리
    p = Pool(processes=5)   # processes를 늘림 ( 3 ~ 5개 적당 )
    print(p.map(func, range(0, 10)))
    
    endTime = int(time.time())
    print('총 작업 시간 : ', (endTime - startTime))
    
    print('-------------------')
    numbers = [1,2,3,4,5]
    procs = []
    
    for idx, number in enumerate(numbers):
        proc = Process(target=doubler, args=(number, ))
        procs.append(proc) # process에 join()을 추가할 의도
        proc.start()
        
    for proc in procs:
        proc.join()
        
<console>
---Process------------------

---Process------------------
값  0 에 대한 작업 process id :  12332

---Process------------------
값  1 에 대한 작업 process id :  6352

---Process------------------
값  2 에 대한 작업 process id :  6864

---Process------------------
값  3 에 대한 작업 process id :  9428

---Process------------------
값  4 에 대한 작업 process id :  7904
값  5 에 대한 작업 process id :  12332
값  6 에 대한 작업 process id :  6864
값  7 에 대한 작업 process id :  6352
값  8 에 대한 작업 process id :  9428
값  9 에 대한 작업 process id :  7904
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
총 작업 시간 :  3
-------------------

---Process------------------
연속적으로 어떤 작업을 진행

---Process------------------
연속적으로 어떤 작업을 진행

---Process------------------
연속적으로 어떤 작업을 진행

---Process------------------
연속적으로 어떤 작업을 진행

---Process------------------
연속적으로 어떤 작업을 진행
num:1, result:11, process id : 12168
num:2, result:12, process id : 12872
num:3, result:13, process id : 12312
num:4, result:14, process id : 12664
num:5, result:15, process id : 2328

pool은 processes에 프로세스의 갯수를 수동으로 넣을 수 있다. 반면 process는 실행 갯수에 대해 그만큼의 프로세스 갯수가 자동으로 들어간다.

둘 다 병렬이지만 pool이 더 쉬움으로 더 많이 쓰인다.