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

Что такое мультитрединг?

2.0 Middle🔥 121 комментариев
#Python Core#Soft Skills

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

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

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

Мультитрединг

Мультитрединг — это механизм, при котором программа может выполнять несколько потоков выполнения (threads) одновременно, обеспечивая параллельное выполнение задач внутри одного процесса.

Основные концепции

Поток (Thread) — это легковесный процесс, который работает в контексте одного процесса и делит с другими потоками общую память, файловые дескрипторы и другие ресурсы. Это делает мультитрединг эффективнее мультипроцессинга для задач с интенсивным обменом данными.

Использование threading в Python

Модуль threading предоставляет удобный API для работы с потоками:

import threading
import time

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

# Создание и запуск потока
thread = threading.Thread(target=worker, args=("Поток-1", 2))
thread.start()
thread.join()  # Ожидание завершения потока

GIL (Global Interpreter Lock)

Одна из ключевых особенностей Python — Global Interpreter Lock (GIL). Это механизм, который позволяет только одному потоку выполнять байт-код Python одновременно, даже на многоядерных системах. Поэтому мультитрединг в Python НЕ дает истинный параллелизм для CPU-bound задач.

import threading
import time

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

# Последовательное выполнение
start = time.time()
cpu_bound_task()
cpu_bound_task()
print(f"Последовательно: {time.time() - start:.2f}s")

# С мультитредингом (медленнее из-за GIL)
start = time.time()
t1 = threading.Thread(target=cpu_bound_task)
t2 = threading.Thread(target=cpu_bound_task)
t1.start()
t2.start()
t1.join()
t2.join()
print(f"Мультитредингом: {time.time() - start:.2f}s")  # Медленнее!

Когда использовать мультитрединг

Мультитрединг эффективен для I/O-bound задач, когда программа ожидает ввода-вывода (сетевые запросы, чтение файлов, работа с БД):

import threading
import requests

def fetch_data(url):
    response = requests.get(url)
    print(f"Получены данные с {url}")
    return response.status_code

urls = ["https://api.example.com/1", "https://api.example.com/2"]
threads = []

for url in urls:
    t = threading.Thread(target=fetch_data, args=(url,))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

В этом примере потоки ждут сетевого ответа независимо друг от друга, что позволяет значительно ускорить выполнение.

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

При одновременной работе потоков часто возникают проблемы с доступом к общим данным. Для синхронизации используются:

Lock (Блокировка):

import threading

lock = threading.Lock()
counter = 0

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

threads = [threading.Thread(target=increment) for _ in range(1000)]
for t in threads:
    t.start()
for t in threads:
    t.join()

print(f"Счётчик: {counter}")  # Всегда 1000

Condition (Условная переменная) — для синхронизации событий между потоками:

import threading

condition = threading.Condition()
data = None

def producer():
    global data
    with condition:
        data = "Новые данные"
        condition.notify_all()  # Уведомляем ожидающие потоки

def consumer():
    with condition:
        condition.wait()  # Ждём уведомления
        print(f"Получены: {data}")

Queue — потокобезопасная очередь для передачи данных между потоками:

from queue import Queue
import threading

q = Queue()

def producer():
    for i in range(5):
        q.put(i)

def consumer():
    while True:
        item = q.get()
        if item is None:
            break
        print(f"Обработан: {item}")
        q.task_done()

t1 = threading.Thread(target=producer)
t2 = threading.Thread(target=consumer)
t1.start()
t2.start()

Альтернативы мультитредингу

  • multiprocessing — для CPU-bound задач, обходит GIL
  • asyncio — для I/O-bound задач, однопоточная асинхронность
  • concurrent.futures — удобные абстракции ThreadPoolExecutor и ProcessPoolExecutor

Выбор между ними зависит от типа задачи и требований к производительности.

Что такое мультитрединг? | PrepBro