2013-10-01 2 views
1

Рассмотрите пример традиционного производства/потребителя. Когда потребитель проверяет размер буфера не равным нулю, есть ли необходимость сигнализировать другие потоки перед ожиданием блокировки? Вот методы код:Существует ли какой-либо тупик в этом коде?

public void consume() 
{ 
    lock(_lock) 
    { 
     while(buf.Count == 0) 
     { 
      // Is there any need to *Monitor.Pulse(_lock);* here? 
      Monitor.Wait(_lock); 
     } 
     // Consume 
    } 
} 

public void produce() 
{ 
    lock(_lock) 
    { 
     // Produce 
     buf.Insert(item); 
     Monitor.PulseAll(_lock); 
    } 
} 

ответ

2

Нет, это не тупиковая ситуация:

  • когда производитель может получить блокировку, он освобождает его немедленно (пульс не прерывает производителя)
  • когда потребитель может получить блокировку, он либо находит данные, или он ожидает (снятие блокировки) соответственно

Там нет сценария, когда производитель заканчивает WAI ting на недостижимом замке. Однако я бы сказал, что PulseAll в потребителе не имеет очевидной цели. Чтобы ответить на другой вопрос:

есть ли необходимость сигнализировать другие темы, не дожидаясь на замок

None вообще, а на самом деле это было бы очень плохая идея, чтобы сделать это. Потому что, если вы это сделали, два потребителя могли бы поддерживать , просыпаясь друг с другом навсегда, хотя нет никакой полезной работы.

Единственный раз, когда полезно пульсировать, когда у вас есть основания полагать, что кто-то ждет, и теперь может что-то сделать. Вы могли бы на самом деле, вероятно, уменьшить его до единственного импульса, если буфер был ранее пустым (т. Е. if(buf.Count == 1)) - потому что если он не был пустым, по-видимому, никто не ждет.

+0

Вы имеете в виду, что код работает даже без каких-либо 'Monitor.Pulse'? – Mehraban

+0

@SAM «Monitor.Pulse» в ** продюсере ** необходим и важен - пробудить ожидающих потребителей. Тем не менее, «Monitor.Pulse» в ** пользователе ** не делает ничего полезного (основанного исключительно на показанном коде) –

+0

Да, это была ошибка в примере, потому что это не фактический код. Я пересмотрел его. – Mehraban

Смежные вопросы