Многопоточность
Многопоточность — это подход к параллельному выполнению задач,
при котором несколько потоков выполняются в рамках одного процесса.
В Python для работы с потоками используется модуль threading
.
Однако из-за Global Interpreter Lock (GIL) многопоточность в Python эффективна только для задач,
связанных с вводом-выводом (I/O-bound), таких как сетевые запросы, чтение файлов или ожидание пользовательского ввода.
- Поток (Thread): Это отдельный поток выполнения внутри процесса. Потоки разделяют общую память.
- GIL (Global Interpreter Lock): В Python GIL ограничивает выполнение только одного потока за раз, что делает многопоточность неэффективной для CPU-bound задач (например, вычислений).
- Использование: Многопоточность подходит для I/O-bound задач, где потоки могут ждать завершения операций ввода-вывода.
Создание потоков
Для создания потоков используется класс threading.Thread
.
-
threading.Thread
: Создаёт новый поток. Аргументtarget
указывает функцию, которую нужно выполнить в потоке, аargs
— аргументы этой функции. -
start()
: Запускает поток. -
join()
: Ожидает завершения потока. Без этого основной поток программы завершится раньше, чем рабочие потоки. -
time.sleep(2)
: Имитирует выполнение задачи, которая занимает 2 секунды.
Потокобезопасные структуры данных
Для обмена данными между потоками используются потокобезопасные структуры, такие как queue.Queue
.
-
queue.Queue
: Потокобезопасная очередь, которая позволяет безопасно обмениваться данными между потоками. -
q.put(i)
: Добавляет элемент в очередь. -
q.get()
: Извлекает элемент из очереди. Если очередь пуста, поток блокируется до появления элемента. -
q.task_done()
: Указывает, что задача выполнена. -
q.put(None)
: Используется как сигнал для завершения работы потребителя.
Блокировки (Locks)
Для синхронизации доступа к общим ресурсам между потоками используются блокировки (threading.Lock
).
-
threading.Lock
: Обеспечивает эксклюзивный доступ к общему ресурсу (в данном случае — переменнойcounter
). -
with lock:
: Блокирует доступ к ресурсу для других потоков, пока текущий поток не завершит операцию.
Рекомендации
- Используйте многопоточность для I/O-bound задач, таких как сетевые запросы, чтение файлов или ожидание пользовательского ввода.
-
Для синхронизации доступа к общим ресурсам используйте блокировки (
threading.Lock
). -
Для обмена данными между потоками используйте потокобезопасные структуры, такие как
queue.Queue
.
Многопоточность в Python — это мощный инструмент для выполнения задач, связанных с вводом-выводом. Используйте её для ускорения операций, которые требуют ожидания (например, сетевые запросы или чтение файлов). Однако помните о GIL, который ограничивает эффективность многопоточности для CPU-bound задач.