, , bar. , , , :
import collections
import contextlib
import threading
lock = threading.Lock()
wait_tracker = collections.defaultdict(lambda: (False, 0, threading.Condition(lock)))
@contextlib.contextmanager
def critical(bar):
with lock:
busy, waiters, condition = wait_tracker[bar]
if busy:
waiters += 1
wait_tracker[bar] = busy, waiters, condition
while wait_tracker[bar][0]:
condition.wait()
busy, waiters, condition = wait_tracker[bar]
waiters -= 1
busy = True
wait_tracker[bar] = busy, waiters, condition
try:
yield
finally:
with lock:
busy, waiters, condition = wait_tracker[bar]
busy = False
if waiters:
wait_tracker[bar] = busy, waiters, condition
condition.notify()
else:
del wait_tracker[bar]
, , :
with critical(bar):
, parallelism , locks-and-shared-memory parallelism. , .