Python Multithreading and Multiprocessing

멀티스레딩과 멀티프로세싱(Multithreading and Multiprocessing in Python)

Multithreading

멀티스레딩은 하나의 프로세스 내에서 여러 스레드를 생성하여 동시에 작업을 수행하는 방식입니다. Python에서 멀티스레딩을 구현하려면 threading 모듈을 사용할 수 있습니다.

멀티스레딩 예제

import threading
import time

def print_numbers():
    for i in range(1, 6):
        print(f'Number: {i}')
        time.sleep(1)

def print_letters():
    for letter in 'abcde':
        print(f'Letter: {letter}')
        time.sleep(1)

# 스레드 생성
thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_letters)

# 스레드 시작
thread1.start()
thread2.start()

# 메인 스레드가 두 스레드가 완료될 때까지 기다림
thread1.join()
thread2.join()

print('Done')

위 코드에서는 두 개의 스레드를 생성하여 동시에 숫자와 문자를 출력합니다. thread1thread2는 각각 print_numbersprint_letters 함수를 실행합니다. start() 메서드를 호출하여 스레드를 시작하고, join() 메서드를 호출하여 메인 스레드가 두 스레드의 완료를 기다리도록 합니다.

스레드 안전성

여러 스레드가 동시에 공유 자원에 접근할 때 데이터 불일치 문제가 발생할 수 있습니다. 이를 방지하기 위해 threading 모듈에서 제공하는 Lock을 사용할 수 있습니다.

import threading

counter = 0
lock = threading.Lock()

def increment_counter():
    global counter
    with lock:
        counter += 1

threads = []
for _ in range(100):
    thread = threading.Thread(target=increment_counter)
    threads.append(thread)
    thread.start()

for thread in threads:
    thread.join()

print(f'Final counter value: {counter}')

위 예제에서는 counter 변수에 100개의 스레드가 동시에 접근하여 값을 증가시키지만, lock을 사용하여 한 번에 하나의 스레드만 counter를 수정할 수 있도록 보장합니다.

Multiprocessing

멀티프로세싱은 여러 개의 프로세스를 생성하여 동시에 작업을 수행하는 방식입니다. Python에서 멀티프로세싱을 구현하려면 multiprocessing 모듈을 사용할 수 있습니다. 멀티프로세싱은 각 프로세스가 독립된 메모리 공간을 가지므로 GIL(Global Interpreter Lock) 제약을 받지 않습니다.

멀티프로세싱 예제

from multiprocessing import Process
import time

def print_numbers():
    for i in range(1, 6):
        print(f'Number: {i}')
        time.sleep(1)

def print_letters():
    for letter in 'abcde':
        print(f'Letter: {letter}')
        time.sleep(1)

# 프로세스 생성
process1 = Process(target=print_numbers)
process2 = Process(target=print_letters)

# 프로세스 시작
process1.start()
process2.start()

# 메인 프로세스가 두 프로세스가 완료될 때까지 기다림
process1.join()
process2.join()

print('Done')

위 코드에서는 두 개의 프로세스를 생성하여 동시에 숫자와 문자를 출력합니다. process1process2는 각각 print_numbersprint_letters 함수를 실행합니다. start() 메서드를 호출하여 프로세스를 시작하고, join() 메서드를 호출하여 메인 프로세스가 두 프로세스의 완료를 기다리도록 합니다.

프로세스 간 통신

멀티프로세싱에서 프로세스 간에 데이터를 주고받기 위해 Queue를 사용할 수 있습니다.

from multiprocessing import Process, Queue

def square_numbers(numbers, queue):
    for n in numbers:
        queue.put(n * n)

numbers = [1, 2, 3, 4, 5]
queue = Queue()

process = Process(target=square_numbers, args=(numbers, queue))
process.start()
process.join()

# 결과 출력
while not queue.empty():
    print(queue.get())

위 예제에서는 square_numbers 함수가 숫자 리스트를 받아 각 숫자의 제곱을 계산한 후 Queue에 넣습니다. 메인 프로세스는 Queue에서 값을 꺼내어 출력합니다.

멀티스레딩과 멀티프로세싱을 사용하면 Python에서 동시에 여러 작업을 효율적으로 수행할 수 있습니다. 멀티스레딩은 가벼운 병렬 처리를 위해 유용하고, 멀티프로세싱은 GIL 제약을 피하기 위해 더 많은 CPU 자원을 사용할 때 유용합니다.

Leave a Reply

Your email address will not be published. Required fields are marked *