Можно ли реализовать многопоточность в Python и как это делается?
Ответ от нейросети
sobes.tech AI
Что хотят услышать интервьюеры:
Да, многопоточность в Python реализуется через модуль threading. Она полезна для задач, где потоки часто ждут ввода-вывода: сеть, файлы, запросы к API. Для CPU-bound задач она обычно не даёт ускорения из-за GIL в CPython.
Определение:
Многопоточность — это выполнение нескольких потоков в рамках одного процесса, где потоки разделяют память процесса. В Python её обычно создают через threading.Thread или через более удобные обёртки вроде concurrent.futures.ThreadPoolExecutor.
Важно понимать ограничение CPython: глобальная блокировка интерпретатора GIL не позволяет нескольким потокам одновременно выполнять байткод Python в нескольких ядрах. Поэтому потоки хороши для параллельного ожидания I/O, но не для тяжёлых вычислений.
Пример использования:
Например, нужно одновременно скачать несколько страниц или отправить несколько HTTP-запросов. Каждый запрос большую часть времени ждёт ответ сервера, и в это время другой поток может работать.
import threading
import requests
def fetch(url):
response = requests.get(url, timeout=5)
print(url, response.status_code)
urls = [
"https://example.com",
"https://httpbin.org/get",
"https://python.org"
]
threads = []
for url in urls:
thread = threading.Thread(target=fetch, args=(url,))
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
Пояснение кода:
- Импортируется модуль
threading, который позволяет создавать и запускать потоки. - Функция
fetchвыполняет сетевой запрос и печатает результат. - Для каждого URL создаётся отдельный объект
Thread, которому передаётся функцияfetchи её аргументы. - Метод
start()запускает поток, и запросы начинают выполняться почти одновременно. - Метод
join()заставляет основной поток ждать завершения всех дочерних потоков, чтобы программа не завершилась раньше времени.
Ключевые моменты:
- Многопоточность в Python есть, и базово она делается через
threading. - Для I/O-bound задач потоки полезны: сеть, файлы, ожидание внешних сервисов.
- Для CPU-bound задач потоки в CPython обычно не ускоряют выполнение из-за GIL.
- Если нужна параллельная CPU-обработка, чаще используют
multiprocessingили выносят вычисления в нативный код. - Для более удобной работы с пулом потоков часто применяют
ThreadPoolExecutor. - Потоки разделяют память, поэтому при работе с общими данными нужно учитывать синхронизацию и возможные race condition.