[Python] Process, Thread

김토리·2025년 1월 27일

Python

목록 보기
1/2

멀티스레드

CPU(Central Processing Unit, 하드웨어)

1 코어는 한 번에 한 시점에 한 가지 일만 할 수 있습니다. 하지만, 인간이 동시 실행을 하고 싶기 때문에, 시간 분할 처리를 하여 동시 실행하는 것 처럼 보이게 하지만 한 번에 한가지 일을 할 때 가장 빠릅니다.

  • 프로세스는 스레드보다 훨씬 무겁기 때문에 heavyweight 컨텍스트 스위칭이라고 합니다. <-> light weight context switching
  • concurrent execution(동시 실행 == 번갈아가며) vs parallel execution(병렬 실행 == 실제로 동시에)
  • multithreading(multiple threads) vs multiprocessing(multiple processes)
  • thread(sub) vs process(main)

멀티 스레딩: I/O (CPU 바깥에서 일어나는 작업)이 쎌 때 유리함 - 키보드, 메모리, 네트워킹(통신) vs 멀티 프로세싱: CPU 안에서 일어나는 작업이 쎌 때 유리함

from concurrent.futures import ThreadPoolExecutor

모듈에서 제공하는 스레드 풀 구현체입니다. 이를 통해 병렬 처리를 쉽게 구현할 수 있습니다.

주요 특징 )

  1. 동시에 여러 작업 실행 가능
  1. 스레드 생성/관리 자동 처리
  1. I/O 바운드 작업(네트워크 요청, 파일 처리 등)에 효과적

=> 주로 여러 웹 API를 동시에 호출하거나, 여러 파일을 동시에 처리하거나, 데이터베이스 쿼리를 병렬로 실행할 때 사용합니다.

=>CPU 집약적인 작업의 경우에는 ProcessPoolExecutor를 사용하는 것이 더 적합할 수 있습니다.


ProcessPoolExecutor : 스레드 대신 별도의 프로세스를 생성해서 작업을 처리합니다.

⭐️ThreadPoolExecutor과의 주요 차이점

  1. Python은 GIL( Global Interpreter Lock)제한을 우회할 수 있어 CPU 집약적 작업에서 더 좋습니다.

각 작업이 별도의 프로세스에서 실행되어 메모리가 격리가 됩니다.

프로세스 생성 비용이 스레드보다 더 큽니다.

주로 대규모 수치계산, 이미지.비디오 처리, 데이터 분석, ML 모델학습 등에 사용됩니다.


@ GIL(Global Interpreter Lock) : Python의 메모리 관리를 위한 mutex(상호배제) 잠금 잠치입니다. 파이썬에서 한 번에 하나의 스레드만 파이썬 코드를 실행할 수 있도록 제한하는 메커니즘입니다.


# GIL로 인해 실제로는 병렬처리가 안되는 예시

import threading

counter = 0

def increment():

    global counter

    for _ in range(1000000):

        counter += 1

# 두 개의 스레드 생성

thread1 = threading.Thread(target=increment)

thread2 = threading.Thread(target=increment)

# 스레드 실행

thread1.start()

thread2.start()



주요 특징

a ) 메모리 관리를 단순화하고 안전하게 함

b ) 단일 스레드 프로그램 성능 향상

c ) 하지만, 멀티코어 CPU에서 Python 스레드의 병렬 처리 제한

📌 이러한 제한을 우회하는 방법들 :

  1. 멀티 프로세싱 사용(ProcessPoolExecutor)

  2. Numpy와 같은 C기반 라이브러리 사용

  3. Cython사용

=> CPU 집약적인 작업을 할 때는 GIL을 우회할 수 있는 멀티프로세싱을 사용하는 것이 더 효율적

 with ThreadPoolExecutor(max_workers=3) as executor:
  • with : Python의 컨텍스트 메니저를 시작합니다. 이는 리소스를 자동으로 관리해주는 구문입니다.

  • ThreadPoolExecutor(max_workers=3) : 최대 3개의 스레드를 가진 스레드 풀을 생성합니다.

  • max_worker = 3 는 동시에 실행될 수 있는 최대 스레드 수를 지정합니다.

  • as executor : 생성된 ThreadPoolExecutor 인스턴스를 executor 변수에 할당합니다.

=> 이 구문은 블록이 끝나면 자동으로 스레드 풀을 정리합니다. & 예외가 발생해도 안전하게 리소스를 해제합니다.

profile
웹 개발하며 데이터 분석, AI 공부하는 jinveloper

0개의 댓글