← Назад к вопросам

Что такое поток (Thread) в Python?

1.3 Junior🔥 221 комментариев
#Асинхронность и многопоточность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Потоки (Threads) в Python

Поток (thread) — это облегчённый процесс выполнения внутри одного процесса Python. Несколько потоков в одном процессе могут работать «параллельно» и делить одно адресное пространство памяти.

Создание потока

Для работы с потоками используется модуль threading:

import threading

def worker(name, delay):
    import time
    print(f"Поток {name} начал работу")
    time.sleep(delay)
    print(f"Поток {name} завершился")

# Создание потока
thread = threading.Thread(target=worker, args=("T1", 2))

# Запуск потока
thread.start()

# Ожидание завершения потока
thread.join()

print("Все потоки завершены")

GIL (Global Interpreter Lock) — ключевое ограничение

Самое важное: В CPython (стандартная реализация Python) существует GIL — глобальная блокировка интерпретатора. GIL предотвращает выполнение Python кода несколькими потоками одновременно.

import threading
import time

def cpu_intensive():
    total = 0
    for i in range(100_000_000):
        total += i
    return total

# Один поток
start = time.time()
cpu_intensive()
print(f"Один поток: {time.time() - start:.2f} сек")

# Два потока
start = time.time()
t1 = threading.Thread(target=cpu_intensive)
t2 = threading.Thread(target=cpu_intensive)
t1.start()
t2.start()
t1.join()
t2.join()
print(f"Два потока: {time.time() - start:.2f} сек")  # Почти не быстрее!

ГIL означает, что многопоточность в Python неэффективна для CPU-bound задач (интенсивные вычисления). Потоки фактически выполняются по очереди, а не параллельно.

Когда потоки полезны: I/O-bound задачи

Потоки хорошо подходят для задач, требующих ожидания (I/O operations):

import threading
import requests
import time

def fetch_url(url):
    print(f"Загружаю {url}...")
    response = requests.get(url, timeout=5)
    print(f"Статус {url}: {response.status_code}")

urls = [
    "https://example.com",
    "https://google.com",
    "https://github.com"
]

# С потоками (быстро)
start = time.time()
threads = [threading.Thread(target=fetch_url, args=(url,)) for url in urls]
for t in threads:
    t.start()
for t in threads:
    t.join()
print(f"С потоками: {time.time() - start:.2f} сек")

Пока один поток ждёт ответ от сервера, другой может работать. GIL отпускается во время I/O операций.

Синхронизация между потоками

Lock (мьютекс) — для защиты общих ресурсов:

import threading

counter = 0
lock = threading.Lock()

def increment():
    global counter
    for _ in range(100_000):
        with lock:  # Защита критической секции
            counter += 1

t1 = threading.Thread(target=increment)
t2 = threading.Thread(target=increment)
t1.start()
t2.start()
t1.join()
t2.join()

print(f"Counter: {counter}")  # 200000 (без lock было бы меньше)

Event — для синхронизации:

event = threading.Event()

def waiter():
    print("Жду события...")
    event.wait()  # Блокируется до set()
    print("Событие произошло!")

def signaler():
    import time
    time.sleep(2)
    event.set()  # Сигнализирует остальным

t1 = threading.Thread(target=waiter)
t2 = threading.Thread(target=signaler)
t1.start()
t2.start()
t1.join()
t2.join()

Альтернативы потокам

Для CPU-bound: используй multiprocessing (отдельные процессы, без GIL):

from multiprocessing import Process

def cpu_task():
    return sum(range(100_000_000))

p1 = Process(target=cpu_task)
p2 = Process(target=cpu_task)
p1.start()
p2.start()
p1.join()
p2.join()

Для I/O-bound: используй asyncio (async/await, коутины):

import asyncio
import aiohttp

async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def main():
    await asyncio.gather(
        fetch("https://example.com"),
        fetch("https://google.com")
    )

asyncio.run(main())

Выводы

  • Потоки — для I/O-bound задач (сеть, файлы)
  • GIL ограничивает параллелизм CPU-bound операций
  • Multiprocessing — для CPU-bound (но тяжелее потоков)
  • Asyncio — современный способ для асинхронного кода