Подскажите, как выполняется данный код:
lock (locker) {
while (x == 0) {
if (y > 0) {
Monitor.Pulse(locker);
break;
}
Monitor.Wait(locker);
}
// что-то еще делаем
}
Задача - синхронизация потоков.
Допустим есть очередь, в которую один поток пишет, другой из нее читает. Вот пока эта очередь пуста, поток "читатель" должен ждать пока не появятся данные.
Я хочу понять для себя, что происходит при вызове Monitor.Wait
и Monitor.Pulse
. Т.е. когда очередь пуста, мы вызываем Monitor.Wait
, поток переходит в режим ожидания, пока ресурс не освободиться (пока не будет данных для чтения), т.е. пока поток "писатель" не запишет данные и не предупредит следующий поток что ресурс скоро освободится командой Monitor.Pulse
.
Вопрос в следующем, когда поток выходит из состояния - Monitor.Wait
, т.е. в цикле while (x == 0)
x
- изменится, будет ли еще раз проверяться условие if (y > 0)
либо же будет исполняться следующий после цикла код?
Когда вы вызовите Wait, то ваш поток освободит блокирующий объект locker
и заблокирует текущий поток. Цикл не завершится.
Функция Wait в потоке1 завершится только тогда, кода другой поток(поток2) вызовет функцию Pulse(или PulseAll) для этого объекта и освободит блокирующий объект. Пока поток2 не освободит объект блокировки, функция Wait
в потоке1 не завершится.
Стоит отметить, что функции Wait, Pulse, PulseAll не могут быть вызваны, если текущий поток не является владельцем блокировки, поэтому обертка их в lock(locker)
обязательна. В противном случае, при вызове этих методов возникнет исключение SynchronizationLockException.
Ниже поясняющий пример работы функций
public static void Main()
{
object locker = new object();
int x = 0;
int y = 0;
Task.Run(() =>
{
Thread.Sleep(2000);
lock (locker)
{
Console.WriteLine("Sending a signal...");
Monitor.Pulse(locker);
Console.WriteLine("The signal was sent");
x = 1;
Thread.Sleep(5000);
Console.WriteLine("Sleep in lock finished");
}
});
lock (locker)
{
while (x == 0)
{
if (y > 0)
{
Monitor.Pulse(locker);
break;
}
Console.WriteLine("Wait...");
Monitor.Wait(locker);
Console.WriteLine("Wait finished");
}
Console.WriteLine("While finished");
}
}
Вывод программы будет следующий:
Wait...
Sending a signal...
The signal was sent
Sleep in lock finished
Wait finished
While finished
Ответ на вопрос: Если Wait
завершится, условие цикла при x !=0
будет false, соответственно цикл завершится и будет выполнятся код после цикла. Повторной проверки y>0
внутри цикла в этом случае невозможна!
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
С помощью сокетов нужно переслать пакет в формате: [имя][время][сообщения]
К примеру есть таблица wp_posts в которой существует колонка post_content
В Sebasee можно создавать времянку сокращенным синтаксисом