Python 멀티스레딩 및 멀티프로세싱

PythonBeginner
지금 연습하기

소개

산업 혁명이 사회를 재편하고, 19 세기 빅토리아 시대의 분주함이 자갈길을 수놓는 세상으로 들어가 보세요. 이곳, 말들이 끄는 마차의 덜거덕거리는 소리와 멀리서 들려오는 공장 기계 소리가 섞인 안개 자욱한 골목길에서, 군중을 사로잡는 재능을 가진 인물이 살고 있습니다. 바로 놀라운 멀티태스킹 능력을 가진 거리 공연가입니다.

올리버라는 이름의 이 공연가는 외발자전거를 타면서 물건을 저글링하고, 하모니카를 연주하며, 복잡한 수수께끼를 동시에 푸는 것으로 유명합니다. 관객들을 놀라게 하는 것은 올리버의 공연이 매끄럽고 효율적이라는 점입니다. 이는 동시 활동에 대한 그의 숙련도를 보여주는 증거입니다. 이 Lab 은 Python 의 멀티스레딩 (multithreading) 및 멀티프로세싱 (multiprocessing) 기능을 탐구하여 올리버의 멀티태스킹 능력을 모방하는 것을 목표로 합니다. 이를 통해 코더 (coder) 들이 문제없이 여러 작업을 동시에 관리할 수 있도록 합니다.

스레드 이해

이 단계에서는 Python 에서 스레딩 (threading) 의 기본 사항을 배우게 됩니다. 스레딩을 사용하면 여러 작업을 동시에 실행할 수 있으며, 마치 프로그램이 한 번에 여러 가지 일을 하는 것처럼 보이게 합니다. 마치 올리버가 자전거를 타면서 저글링하는 능력과 같습니다.

~/project 디렉토리에 simple_threads.py라는 파일을 열고 다음 내용을 입력하세요.

import threading
import time

def print_numbers():
    for i in range(1, 6):
        time.sleep(1)
        print(i)

## Create two threads
thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_numbers)

## Start both threads
thread1.start()
thread2.start()

## Wait for both threads to complete
thread1.join()
thread2.join()

print("Done with numbers!")

터미널에서 다음 명령으로 위의 코드를 실행합니다.

python simple_threads.py

두 스레드에서 숫자가 번갈아 가며 출력된 후 "Done with numbers!"가 표시되어야 합니다.

1
1
2
2
3
3
4
4
5
5
Done with numbers!

멀티프로세싱 활용

이제 멀티프로세싱 (multiprocessing) 을 사용하여 계산 속도를 높여 보겠습니다. Python 의 멀티프로세싱은 여러 프로세스를 실행할 수 있게 해주며, 이는 서로 다른 CPU 코어에서 실행될 수 있어 CPU 바운드 (CPU-bound) 작업에 필요한 총 시간을 줄여줍니다.

~/project 디렉토리에 process_prime.py라는 파일을 열고 다음 내용을 입력하세요.

from multiprocessing import Process
import math

def is_prime(num):
    """
    Check if a number is prime.
    """
    if num <= 1:
        return False
    for i in range(2, int(math.sqrt(num)) + 1):
        if num % i == 0:
            return False
    return True

def compute_primes(start, end):
    """
    Compute prime numbers within a given range.
    """
    prime_numbers = [num for num in range(start, end) if is_prime(num)]
    print(f"Primes in range {start}-{end}: {prime_numbers}")

processes = []
## Creating two processes
for i in range(0, 20000, 10000):
    ## Create a new process targeting the compute_primes function and passing the range as arguments
    p = Process(target=compute_primes, args=(i, i+10000))
    processes.append(p)
    ## Start the process
    p.start()

## Wait for all processes to finish
for p in processes:
    p.join()

print("Done with prime computation!")

터미널에서 스크립트를 실행합니다.

python process_prime.py

그러면 지정된 범위에서 발견된 소수가 출력되고 완료 메시지가 표시됩니다.

Primes in range 0-10000: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241,
 ... ...
9851, 9857, 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973]
Primes in range 10000-20000: [10007, 10009, 10037, 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, 10169, 10177, 10181, 10193,
 ... ...
19739, 19751, 19753, 19759, 19763, 19777, 19793, 19801, 19813, 19819, 19841, 19843, 19853, 19861, 19867, 19889, 19891, 19913, 19919, 19927, 19937, 19949, 19961, 19963, 19973, 19979, 19991, 19993, 19997]
Done with prime computation!

요약

이 랩에서는 Python 에서 스레딩 (threading) 과 멀티프로세싱 (multiprocessing) 의 뉘앙스를 파헤치는 흥미로운 여정을 시작했습니다. 마치 빅토리아 시대 거리 예술가들의 다층적인 공연과 같았습니다. 스레드를 사용하여 작업을 저글링하는 것부터 시작하여 CPU 코어 전체에서 대규모 작업을 처리하는 것으로 확장했습니다. 이 연습은 Python 의 병렬 처리 기능을 보여주었을 뿐만 아니라, 이러한 기술이 우리 캐릭터 올리버의 다면적인 기술 시연과 유사하게 실제 세계에서 어떤 의미를 갖는지 보여주었습니다.

이 랩에서 얻어야 할 핵심은 I/O 바운드 (I/O-bound) 작업에 대한 Python 스레드와 CPU 바운드 (CPU-bound) 작업에 대한 프로세스에 대한 명확한 이해를 갖는 것입니다. 이는 코딩 성능을 효과적으로 향상시키고 애플리케이션을 더욱 효율적으로 만들 것입니다.