Pulse в C#
Метод Monitor.Wait освобождает монитор и ставит поток в очередь ожидания, а Pulse будит один такой поток. Вызов Pulse возможен только пока текущий поток держит lock на том же объекте, иначе будет SynchronizationLockException.
Метод Wait всегда вызывают внутри lock и проверяют условие в цикле while, а не if: после пробуждения условие может ещё не выполняться (ложное пробуждение или другой поток успел изменить состояние).
Рабочий поток ждёт, пока главный не поднимет флаг и не пошлёт сигнал. Короткая пауза перед сигналом даёт ему успеть дойти до ожидания, иначе сигнал пропадёт. Поток выходит из цикла только когда done стал true:
object gate = new();
bool done = false;
int wake = 0;
Thread w = new(() =>
{
lock (gate)
{
while (!done)
Monitor.Wait(gate);
wake = 1;
}
});
w.Start();
Thread.Sleep(10);
lock (gate)
{
done = true;
Monitor.Pulse(gate);
}
w.Join();
Console.WriteLine(wake); // выведет 1
В рабочем потоке дождитесь разрешения и затем запишите в общее поле число 4. В главном потоке выставьте разрешение и разбудите ждущего. Дождитесь рабочего потока и выведите записанное число.