Синхронизация монитора: реализация нескольких переменных условий - PullRequest
1 голос
/ 30 сентября 2010

Я осуществляю синхронизацию монитора.Мне было интересно, как работает реализация нескольких условных переменных.Таким образом, условная переменная имеет метод wait (), который помещает его в очередь ожидания для конкретной блокировки, связанной с этой условной переменной.Итак, если у меня есть несколько переменных условия, каждый вызов ожидания создает свою отдельную очередь ожидания?Например, если у меня есть:

lock = Lock()  
A = Condition(lock)  
B = Condition(lock)  
C = Condition(lock)  

def foo:  
     with lock:  
        while true:  
            A.wait()  

def bar:  
    with lock:  
        while true:  
            B.wait()  

def notifyA  
    with lock:  
        A.notifyAll()  

Итак, мой вопрос в том, что когда мы выполняем A.notifyAll (), он только пробуждает вещи в очереди A.wait или это объединенная очередьс замком.

1 Ответ

2 голосов
/ 01 октября 2010

A.notifyAll() должен только пробудить поток, работающий foo(). Очередь ожидания, в которой находятся ваши потоки wait(), является частью условной переменной , а не lock . У блокировки есть собственная очередь ожидания, но она используется только потоками, пытающимися получить блокировку. Когда ваш поток спит в резюме, он не удерживает блокировку и не будет пытаться повторно получить его, пока другой поток не вызовет notify() или подобное.

Тем не менее, вы должны написать свой код, предполагая, что B.wait() действительно может проснуться в любое время. Практически это означает повторную проверку состояния, в котором ожидает поток:

    with lock:
        while not ready:
            B.wait()
        # Do stuff with protected data
...