0Pricing
Python Academy · 강의

스레드와 GIL

Python 스레딩의 한계 이해하기

스레드와 GIL은(는) CoddyKit의 무료 Python Academy 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Python Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Python Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

Thread란 무엇인가요

스레드는 하나의 프로세스 안에서 실행되는 별도의 실행 흐름입니다. Python의 threading 모듈을 사용하면 하나의 프로그램 안에서 함수를 동시에 실행할 수 있습니다.

import threading

def worker():
    print('hello from thread')

t = threading.Thread(target=worker)
t.start()
t.join()
print('main done')

여러 스레드 시작하기

여러 스레드를 시작할 수 있습니다. 각 스레드는 대상 함수를 실행합니다. join()은 주 스레드가 스레드의 실행이 끝날 때까지 기다리게 합니다.

import threading

def task(name):
    print('task', name)

threads = [threading.Thread(target=task, args=(i,)) for i in range(3)]
for t in threads:
    t.start()
for t in threads:
    t.join()
print('all finished')

전역 인터프리터 잠금

CPython에는 전역 인터프리터 잠금(GIL)이 있습니다. 한 번에 하나의 스레드만 Python 바이트코드를 실행할 수 있습니다. 따라서 순수 Python으로 수행하는 CPU 작업에서는 스레드가 진정한 병렬 속도 향상을 제공하지 못합니다.

import sys
print('Running on:', sys.implementation.name)
print('Only one thread runs Python bytecode at a time due to the GIL')

스레드가 여전히 유용한 경우

스레드는 입출력 중심 작업에 특히 유용합니다. 네트워크 요청, 디스크 읽기, 대기 등이 그 예입니다. 한 스레드가 기다리는 동안 GIL이 해제되어 다른 스레드가 실행될 수 있습니다.

import threading, time

def fake_io(name):
    time.sleep(0.1)
    print('done', name)

start = time.perf_counter()
ts = [threading.Thread(target=fake_io, args=(i,)) for i in range(3)]
for t in ts: t.start()
for t in ts: t.join()
print('elapsed about 0.1s, not 0.3s')

CPU 중심 작업은 빨라지지 않음

계산량이 많은 작업에서는 GIL이 스레드 실행을 직렬화하므로 스레드를 추가해도 더 빨라지지 않습니다. CPU 작업에는 대신 multiprocessing을 사용하세요.

import threading

def burn():
    total = 0
    for i in range(1000000):
        total += i
    return total

t = threading.Thread(target=burn)
t.start()
t.join()
print('CPU-bound: threads share one core under the GIL')

데몬 스레드

데몬 스레드는 주 프로그램이 종료될 때 자동으로 종료됩니다. 기다릴 필요가 없는 background 도우미에 사용하세요.

import threading, time

def background():
    time.sleep(0.05)
    print('background tick')

t = threading.Thread(target=background, daemon=True)
t.start()
t.join()
print('main exits')

스레드 이름 지정 및 식별하기

각 스레드에는 이름과 ID가 있습니다. threading.current_thread()는 현재 실행 중인 스레드 객체를 반환하므로 로그 기록에 유용합니다.

import threading

def show():
    t = threading.current_thread()
    print('running in', t.name)

t = threading.Thread(target=show, name='Worker-1')
t.start()
t.join()
print('main thread:', threading.current_thread().name)

Thread 서브클래싱

대상을 전달하는 대신 Thread를 상속하고 run()을 재정의할 수 있습니다. 스레드에 자체 상태가 필요할 때 유용합니다.

import threading

class Greeter(threading.Thread):
    def __init__(self, name):
        super().__init__()
        self.who = name
    def run(self):
        print('hi', self.who)

g = Greeter('Sam')
g.start()
g.join()

스레드에서 결과 반환하기

대상 함수의 반환값은 버려집니다. 결과를 수집하려면 공유 자료 구조에 결과를 기록하세요. 나중에는 큐와 같은 더 안전한 도구를 살펴봅니다.

import threading

results = {}

def compute(key):
    results[key] = key * key

ts = [threading.Thread(target=compute, args=(i,)) for i in range(4)]
for t in ts: t.start()
for t in ts: t.join()
print(results)

활성 스레드 수 세기

threading.active_count()는 현재 살아 있는 스레드 수를 알려 줍니다. 주 스레드도 포함됩니다.

import threading, time

def wait():
    time.sleep(0.05)

ts = [threading.Thread(target=wait) for _ in range(2)]
for t in ts: t.start()
print('active now:', threading.active_count())
for t in ts: t.join()
print('active after join:', threading.active_count())

스레드와 프로세스 중 선택하기

일반적인 기준은 다음과 같습니다. 입출력 중심 동시성에는 스레드를 사용하고, CPU 중심 병렬 처리에는 프로세스를 사용하세요. 그 이유는 GIL 때문입니다.

tasks = {'download files': 'threads', 'crunch numbers': 'processes', 'call APIs': 'threads'}
for task, choice in tasks.items():
    print(task, '->', choice)

빠른 확인

스레드와 GIL에 대한 이해도를 확인해 보세요.

복습

스레드와 GIL에 대해 배웠습니다.

  • 스레드는 threading.Thread를 통해 하나의 프로세스 안에서 동시에 실행됩니다.
  • GIL은 Python 바이트코드 실행을 직렬화합니다.
  • 스레드는 입출력 중심 작업에, 프로세스는 CPU 중심 작업에 유용합니다.
  • start(), join(), 데몬 스레드 및 상속을 사용합니다.

다음에는 ThreadPoolExecutor로 스레드를 깔끔하게 관리하는 방법을 배웁니다.

자주 묻는 질문

“스레드와 GIL” 강의는 무료인가요?

네 — “스레드와 GIL” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Python Academy 강의 전체를 잠금 해제할 수 있습니다. Python Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“스레드와 GIL”에서 뭘 배우나요?

Python 스레딩의 한계 이해하기 브라우저에서 직접 실행하는 실습 코드로 Python Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Python Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Python Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.

“스레드와 GIL” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Python Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Python Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 스레드와 GIL
  2. ThreadPoolExecutor
  3. multiprocessing 기초
  4. 안전한 데이터 공유
← Python Academy(으)로 돌아가기