Что на самом деле делают System.TMonitor.Pulse и TMonitor.PulseAll в Delphi

Мне было очень приятно видеть, что Delphi представила запись TMonitor в Delphi 2009, позволяющую блокировать определенные объекты в многопоточной среде. Что меня озадачило, так это методы Pulse и PulseAll этого типа записи.

Например, запись для Pulse в справке Delphi гласит: «Уведомляет следующий поток в очереди ожидания, что он сможет заблокировать указанный объект, как только вызывающий поток освободит объект».

Действительно? Что это обозначает? Я без проблем использовал TMonitor без использования Pulse. Кроме того, в некоторых случаях использования TMonitor в исходном коде Delphi никогда не используется Pulse.

Включены ли методы Pulse и PulseAll в запись Delphi TMonitor только для совместимости на уровне исходного кода с классом .NET Monitor, или они действительно служат какой-то цели?

Есть два вопроса («TMonitor.Pulse vs TMonitor.PulseAll» и "Для чего подходит модуль TMonitor в системе Delphi"), поговорим по этому вопросу, но я ищу окончательный ответ.


person Cary Jensen    schedule 29.08.2011    source источник


Ответы (1)


Ссылка на википедию в моем ответе на упомянутый вопрос содержит обсуждение использования функции монитора wait / pulse / pulseall. Поток должен войти в монитор, который они вызывают. Затем другой поток должен войти в монитор и вызвать pulse или pulseall, чтобы сигнализировать первому ожидающему потоку. Pulse сигнализирует только об одном ожидающем потоке, тогда как pulseall сигнализирует обо всех ожидающих потоках. Посмотрите раздел условных переменных в статье в Википедии для более подробного обсуждения. Также в RTL-источнике есть комментарии, описывающие методы TMonitor.

person Allen Bauer    schedule 29.08.2011
comment
@johan Очевидно, Wait и Pulse не работают должным образом. Пару месяцев назад об этом много писали в блогах Крис Роллистон, Примоз, Эрик Грейндж и т. Д. - person David Heffernan; 29.08.2011
comment
Аллен говорил об исправлении во время его обсуждения, и я считаю, что он в состоянии выполнить его. - person LU RD; 29.08.2011
comment
@Johan, вот ссылка, как воспроизвести брешь в TMonitor, stackoverflow.com/questions/4856306/ - person LU RD; 29.08.2011
comment
Спасибо, Аллен. Если я правильно прочитал ваши комментарии, Pulse и PulseAll применяются только тогда, когда поток, заблокировавший объект, вызывает Wait, чтобы временно снять блокировку с другого потока. Что касается потока, пытающегося получить блокировку с помощью Enter или TryEnter, Pulse и PulseAll не применяются. Что еще хуже, в тестовом приложении я заблокировал объект, попытался войти в эту блокировку с другим потоком, вызванным Wait в первом потоке, когда ожидающий поток вступил во владение. Затем второй поток освободил эту блокировку, после чего исходный поток восстановил блокировку. Звонки в Pulse не использовались. - person Cary Jensen; 29.08.2011
comment
@ Кэри, если у вас есть тестовый пример, я бы хотел его увидеть. Звучит неправильно. Ожидание должно блокироваться, пока Pulse или PulseAll не будет вызван из другого потока. - person Allen Bauer; 03.09.2011