파이썬은 GIL로 인해 여러 스레드가 순차적으로 실행되는 직렬 구조로 동작한다. GIL에 대한 내용은 여기를 참고하자. 병렬 처리를 구현하기 위한 여러가지 모듈 중에서 thread
와 process
모듈을 테스트해봤다.
두 모듈을 사용해서 x
라는 변수에 1을 1000만번을 더하는 함수를 만들어 두 번씩 실행해 볼 것이다. 변수 x
의 최종값과, 코드를 실행하는데 걸리는 시간을 출력한다.
from threading import Thread
import time
start = time.time()
def work(id, start, end, result):
total = 0
for _ in range(start, end):
total += 1
result.append(total)
return
if __name__ == "__main__":
START, END = 0, 100000000
result = list()
th1 = Thread(target=work, args=(1, START, END, result))
th1.start()
th1.join()
print(f"Result: {sum(result)}")
print("time :", time.time() - start)
if __name__ == "__main__":
START, END = 0, 100000000
result = list()
th1 = Thread(target=work, args=(1, START, END//2, result))
th2 = Thread(target=work, args=(2, END//2, END, result))
th1.start()
th2.start()
th1.join()
th2.join()
print(f"Result: {sum(result)}")
print("time :", time.time() - start)
from multiprocessing import Process, Queue
import time
start = time.time()
def work(id, start, end, result):
total = 0
for _ in range(start, end):
total += 1
result.put(total)
return
if __name__ == "__main__":
START, END = 0, 100000000
result = Queue()
th1 = Process(target=work, args=(1, START, END//2, result))
th1.start()
th1.join()
result.put('STOP')
total = 0
while True:
tmp = result.get()
if tmp == 'STOP':
break
else:
total += tmp
print(f"Result: {total}")
print("time :", time.time() - start)
if __name__ == "__main__":
START, END = 0, 100000000
result = Queue()
th1 = Process(target=work, args=(1, START, END//2, result))
th2 = Process(target=work, args=(2, END//2, END, result))
th1.start()
th2.start()
th1.join()
th2.join()
result.put('STOP')
total = 0
while True:
tmp = result.get()
if tmp == 'STOP':
break
else:
total += tmp
print(f"Result: {total}")
print("time :", time.time() - start)
\ | Thread | Process |
---|---|---|
장점 | 메모리 공간을 적게 차지한다. 다른 스레드로 전환이 빠르다. (context switching) | 다른 프로세스에 영향을 주지 않아 안정성이 높다. |
단점 | 스레드 하나의 문제가 다른 스레드에 영향을 준다. 동기화 문제가 발생할 수 있다(병목현상, 데드락 등). | CPU시간을 많이 차지한다. 작업량이 많을수록 switching이 많이 일어난다. (오버헤드가 발생할 수 있음) |
[참고사이트]
Python 공식문서 : 병렬 처리 모듈
[Python] 파이썬 멀티 쓰레드(thread)와 멀티 프로세스(process)
멀티 프로세스(Multi Process)와 멀티 스레드(Multi Thread)