Ответ
Многопоточность в Python реализована через модуль threading
, но ее ключевой особенностью является Global Interpreter Lock (GIL).
GIL — это механизм в стандартном интерпретаторе CPython, который позволяет выполняться только одному потоку с Python-байткодом в один момент времени. Из-за этого потоки не могут по-настоящему параллельно выполняться на нескольких ядрах процессора.
Когда threading
эффективен:
- I/O-bound задачи (ограниченные вводом-выводом): сетевые запросы, работа с файлами, обращение к базам данных. В этих случаях поток отдает GIL, пока ждет ответа, позволяя другим потокам работать.
Когда threading
неэффективен:
- CPU-bound задачи (ограниченные производительностью процессора): сложные математические вычисления, обработка изображений. Здесь GIL не будет освобождаться, и реального ускорения на многоядерной системе не произойдет.
Пример (симуляция I/O-задачи):
import threading
import time
def io_task():
print(f"Поток {threading.current_thread().name} начал I/O операцию")
time.sleep(2) # Симуляция ожидания ответа от сети или диска
print(f"Поток {threading.current_thread().name} завершил операцию")
start_time = time.time()
threads = [
threading.Thread(target=io_task, name=f"T-{i}") for i in range(3)
]
for t in threads:
t.start()
for t in threads:
t.join() # Ожидаем завершения всех потоков
print(f"Все потоки завершились за {time.time() - start_time:.2f} секунд.")
# Вывод: Все потоки завершились за ~2.00 секунд (а не за 6).
Альтернативы для CPU-bound задач:
multiprocessing
: Создает отдельные процессы со своим GIL, позволяя достичь настоящего параллелизма.asyncio
: Для высокоэффективного асинхронного I/O в одном потоке.