проблема спящего брадобрея
Oct. 27th, 2009 11:22 pmа вот это, наоборот, явно можно сделать проще, даже когда брадобреев много.
// вначале семафор закрыт
newCustomer = new AutoResetEvent(false);
// customer reception thread[s]
lock (queue) {
if (queue.Size == maxSize)
throw "нет мест";
queue.Enqueue(сustomer);
newCustomer.Set(); // open semaphore
}
// each barber's thread
while (true) {
newCustomer.WaitOne(); // let one barber through and close
lock (queue) {
if (queue.IsEmpty)
continue;
customer = queue.Dequeue();
}
Shave(customer);
}собственно, этот же код решает и проблему продюсеров-консъюмеров, вместо того, что там написано (на буфер памяти нет, а спящие треды копить память есть, да?)
(no subject)
Date: 2009-11-03 10:50 pm (UTC)Меня вот что запутало: я же правильно понимаю, что в очереди next никогда не должно быть больше одного кастомера, то есть её можно смело превратить в `Customer next;` и вместо `if (next.count > 0)` писать `if (next != null)`, ну а вместо `next.Dequeue` -- `customer = next; next = null`?
Тогда да, кажется тоже работает.
(no subject)
Date: 2009-11-03 10:54 pm (UTC)(no subject)
Date: 2009-11-03 11:03 pm (UTC)и куда его совать-то, этот volatile? вместо локов не получится, локи всё равно нужны. а тогда лишний point of synchronization. но всё равно не понимаю, куда.
(no subject)
Date: 2009-11-03 11:17 pm (UTC)В принципе может быть это и не нужно в данном конкретном случае -- lock сам по себе вроде бы является read-write barrier (но вот насчёт read не уверен, кстати!), однако над такими вещами лучше не задумываться излишне, по-моему.
Не, это barberAwakeningPending имелось в виду!
(no subject)
Date: 2009-11-04 02:05 am (UTC)и да, lock - это всегда both read and write barrier, (иначе бы не работало ничего).
(no subject)
Date: 2009-11-03 11:00 pm (UTC)