파이썬 - 다중 스레드
안녕하세요, 미래의 파이썬 마법사 여러분! 오늘은 파이썬에서 다중 스레드의 세계로 흥미진진한 여정을 떠날 거예요. 프로그래밍에 처음이라도 걱정 마세요. 저는 여러분의 친한 가이드가 될 테니까, 이 주제를 단계별로 탐구해볼 거예요. 그럼, 가상의 마법봉을 준비해 (키보드를), 함께 뛰어들어볼까요!
다중 스레드란 무엇인가요?
파이썬 스레드로 마법을 부를 때까지 기다리지 마세요. 먼저 다중 스레드가 무엇인지 이해해야 해요. 바쁜 주방에서 저는 셰프라고 상상해봅시다. 혼자서 요리를 하면 한 번에 하나의 일만 할 수 있어요 - 채소를 다듬고, 물을 끓이고, 고기를 볶는 식입니다. 하지만 여러 손을 가지고 다른 일을 동시에 할 수 있다면 어떤가요? 이것이 바로 다중 스레드가 프로그램에 던지는 매커니즘입니다!
다중 스레드는 단일 프로세스 내에서 여러 작업을 동시에 실행할 수 있게 해줍니다. 여러 셰프(스레드)가 동일한 주방(프로세스)에서 함께 일하며 더 빠르고 효율적으로 맛있는 음식(프로그램 출력)을 준비하는 것과 같아요.
프로세스와의 비교
이제, "하지만 선생님, 프로세스에 대해서도 들었어요. 스레드와 프로세스의 차이는 무엇인가요?"라고 궁금해할지도 모르겠어요. ع락하죠, 이건 잘 설명해 드릴게요:
-
리소스 사용: 스레드는 방을 공유하는 형제(메모리 공간)처럼, 프로세스는 별도의 집을 가진 이웃처럼입니다. 스레드는 더 가볍고 리소스를 공유하여 특정 작업에 더 효율적입니다.
-
커뮤니케이션: 스레드는 변수를 공유하여 쉽게 대화할 수 있지만, 프로세스는 서로에게 이야기하려면 특별한 "전화기"(프로세스 간 커뮤니케이션)를 사용해야 합니다.
-
오버헤드: 스레드를 생성하고 관리하는 것은 일반적으로 프로세스보다 더 빠르고 적은 시스템 리소스를 필요로 합니다.
-
복잡성: 스레드는 프로그램을 더 빠르게 할 수 있지만, 복잡성을 도입합니다. 마치 공중 투구를 할 때처럼 - 잘 하면 재미있고 효율적이지만, 신중하지 않으면 볼을 떨어트릴 수도 있습니다!
파이썬에서의 스레드 처리 모듈
파이썬은 용맹한 언어이므로 우리에게 스레드를 작업할 수 있는 여러 모듈을 제공합니다. 주요 두 가지는 다음과 같습니다:
-
threading: 이것은 스레드를 작업할 때 사용하는 고수준 인터페이스입니다. 마치 여러분의 친한 마법사 학생처럼 많은 무거운 일을 대신 해줍니다.
-
_thread: 이것은 저수준 인터페이스입니다. 마치 오래된 마법책처럼 강력하지만, 올바르게 사용하려면 더 많은 전문 지식이 필요합니다.
오늘의 마법적 여정에서는 더 비전문가 친화적이고 널리 사용되는 threading
모듈에 집중할 거예요.
새 스레드 시작
좋아요, 우리의 첫 번째 스레드 마법을 부를 차례입니다! 여기서는 새 스레드를 생성하고 시작하는 방법을 보여드릴게요:
import threading
import time
def print_numbers():
for i in range(5):
time.sleep(1)
print(f"Thread 1: {i}")
# 새 스레드 생성
thread1 = threading.Thread(target=print_numbers)
# 스레드 시작
thread1.start()
# 메인 스레드는 계속 실행
for i in range(5):
time.sleep(1)
print(f"Main thread: {i}")
# thread1이 끝날 때까지 기다리기
thread1.join()
print("All done!")
이 마법의 부르는 방법을 분석해봅시다:
-
threading
와time
모듈을 임포트합니다. -
print_numbers()
함수를 정의하여 스레드가 실행할 함수입니다. - 새 스레드 객체를 생성하고, 실행할 함수를 지정합니다.
-
start()
메서드를 사용하여 스레드를 시작합니다. - 메인 스레드는 자신의 루프를 계속 실행합니다.
-
join()
을 사용하여 프로그램을 끝내기 전에 우리의 스레드가 끝날 때까지 기다립니다.
이 코드를 실행하면, 스레드 간의 번갈아가는 번호를 보며 동시 실행을 보여줄 거예요!
스레드 동기화
이제, 우리의 셰프 도우미가 같은 도구를 동시에 사용하려고 시도하는 상황을 상상해봅시다 - 혼란스러울 텐데요? 이때는 스레드 동기화가 필요합니다. 우리는 한 번에 하나의 스레드만이 공유 자원에 접근할 수 있도록 록을 사용합니다.
여기 예제를 보여드릴게요:
import threading
import time
# 공유 자원
counter = 0
lock = threading.Lock()
def increment_counter():
global counter
for _ in range(100000):
lock.acquire()
counter += 1
lock.release()
# 두 개의 스레드 생성
thread1 = threading.Thread(target=increment_counter)
thread2 = threading.Thread(target=increment_counter)
# 스레드 시작
thread1.start()
thread2.start()
# 두 스레드가 모두 끝날 때까지 기다리기
thread1.join()
thread2.join()
print(f"Final counter value: {counter}")
이 예제에서는 록을 사용하여 한 번에 하나의 스레드만이 카운터를 증가시킬 수 있도록 하여 경쟁 상황을 방지합니다.
다중 스레드 우선순위 큐
마지막으로, 다중 스레드의 실용적인 응용 사례 중 하나를 살펴보겠습니다 - 우선순위 큐입니다. 병원 응급실에서 환자들이 상황의 심각성에 따라 치료를 받는다는 것을 상상해봅시다.
import threading
import queue
import time
import random
# 우선순위 큐 생성
task_queue = queue.PriorityQueue()
def worker():
while True:
priority, task = task_queue.get()
print(f"Processing task: {task} (Priority: {priority})")
time.sleep(random.uniform(0.1, 0.5)) # 작업 시뮬레이션
task_queue.task_done()
# 워커 스레드 생성하고 시작
for _ in range(3):
thread = threading.Thread(target=worker, daemon=True)
thread.start()
# 큐에 작업 추가
for i in range(10):
priority = random.randint(1, 5)
task = f"Task {i}"
task_queue.put((priority, task))
# 모든 작업이 완료될 때까지 기다리기
task_queue.join()
print("All tasks completed!")
이 예제는 여러 스레드가 우선순위 큐에서 작업을 효율적으로 처리하는 방법을 보여줍니다.
결론
축하합니다, 어린 파이썬 마법사 여러분! 여러분은 파이썬의 다중 스레드 세계로 첫 걸음을 내딛었습니다. 기억하세요, 위대한 힘은 위대한 책임과 함께 옵니다 - 스레드를 지혜롭게 사용하면 프로그램을 더 빠르고 효율적으로 만들 수 있습니다.
여기 우리가 다룬 주요 스레드 메서드의 빠른 참조 표가 있습니다:
메서드 | 설명 |
---|---|
Thread(target=function) |
지정된 함수를 실행할 새 스레드를 생성합니다 |
start() |
스레드의 활동을 시작합니다 |
join() |
스레드가 완료될 때까지 기다립니다 |
Lock() |
스레드 동기화를 위한 록을 생성합니다 |
acquire() |
록을 획득합니다 |
release() |
록을 반납합니다 |
숙지하고, 호기심을 지켜봐, 곧 스레드를 마치 음악술가처럼 협상할 수 있는 파이썬 마estro가 될 거예요! 즐거운 코딩!
Credits: Image by storyset