Все объекты, предоставляемые модулем threading
, у которых есть методы .acquire()
и .release()
, могут использоваться в качестве менеджеров контекста для оператора with
.
Блокировки реализуют API контекстного менеджера и совместимы с оператором with
. Использование with
устраняет необходимость явно устанавливать и снимать блокировку.
Метод .acquire()
будет вызываться при входе в блок with
, а метод .release()
будет вызываться при выходе из блока with
. Отсюда следующий фрагмент:
with some_lock: # do something...
Что эквивалентно:
some_lock.acquire() try: # do something... finally: some_lock.release()
В настоящее время могут использоваться как с менеджерами контекста объекты threading.Lock()
, threading.RLock()
, threading.Condition()
, threading.Semaphore()
и threading.BoundedSemaphore()
.
В примере две функции worker_with()
и worker_finally()
управляют блокировкой эквивалентными способами.
import threading def worker_with(lock): with lock: th_name = threading.current_thread().name print(f'{th_name}: блокировка ставится через `with`') def worker_finally(lock): lock.acquire() try: th_name = threading.current_thread().name print(f'{th_name}: блокировка ставится явно') finally: lock.release() lock = threading.Lock() wh = threading.Thread(target=worker_with, args=(lock,)) fin = threading.Thread(target=worker_finally, args=(lock,)) wh.start() fin.start() # Thread-1: блокировка ставится через `with` # Thread-2: блокировка ставится явно