Ответ
Примитивы синхронизации — это базовые механизмы, используемые в многопоточном или многопроцессном программировании для координации доступа к общим ресурсам и предотвращения проблем, таких как состояния гонки (race conditions) и взаимоблокировки (deadlocks).
В Python модуль threading предоставляет следующие основные примитивы:
-
Lock(Блокировка)- Назначение: Самый простой примитив для обеспечения взаимного исключения. Позволяет только одному потоку одновременно выполнять критическую секцию кода.
-
Пример:
from threading import Lock shared_data = 0 lock = Lock() def increment(): global shared_data with lock: # Захватывает блокировку, гарантируя эксклюзивный доступ shared_data += 1
-
RLock(Реентерабельная блокировка)- Назначение: Позволяет одному и тому же потоку захватывать блокировку несколько раз без возникновения взаимоблокировки. Это полезно, когда функция, уже владеющая блокировкой, вызывает другую функцию, которая также пытается захватить ту же блокировку.
-
Пример:
from threading import RLock r_lock = RLock() def func1(): with r_lock: # Первый захват print("Func1 acquired lock") func2() def func2(): with r_lock: # Второй захват тем же потоком print("Func2 acquired lock")
-
Semaphore(Семафор)- Назначение: Ограничивает количество потоков, которые могут одновременно получить доступ к ресурсу или выполнить определенную секцию кода. Используется для управления пулом ресурсов.
-
Пример:
from threading import Semaphore # Разрешает до 3 потоков одновременно sem = Semaphore(3) def worker(name): import time with sem: # Захватывает семафор (уменьшает счетчик) print(f"Поток {name} работает с ресурсом...") # Имитация работы time.sleep(1) print(f"Поток {name} завершил работу.") # Семафор освобождается при выходе из 'with' (увеличивает счетчик)
-
Event(Событие)- Назначение: Простой механизм для сигнализации между потоками. Один поток ждет, пока событие не будет установлено, а другой поток устанавливает его.
-
Пример:
from threading import Event event = Event() def waiter(): print("Ожидающий поток: жду события...") event.wait() # Блокируется, пока событие не будет установлено print("Ожидающий поток: событие получено!") def setter(): import time time.sleep(2) print("Устанавливающий поток: устанавливаю событие.") event.set() # Разблокирует все ожидающие потоки
-
Condition(Условие)- Назначение: Более сложный механизм, позволяющий потокам ждать выполнения определенного условия и быть уведомленными, когда это условие становится истинным. Часто используется для реализации паттерна "производитель-потребитель".
-
Пример:
from threading import Condition items = [] condition = Condition() def producer(): with condition: # Захватывает связанный Lock items.append("item") print("Производитель: добавил элемент.") condition.notify() # Уведомляет один ожидающий поток def consumer(): with condition: # Захватывает связанный Lock while not items: # Ждем, пока условие не станет истинным print("Потребитель: жду элементы...") condition.wait() # Освобождает Lock и ждет уведомления item = items.pop(0) print(f"Потребитель: обработал {item}.")
Эти примитивы являются строительными блоками для создания надежных и эффективных многопоточных приложений, помогая управлять доступом к общим данным и координировать выполнение задач.