Нужно ли запланировать поток, ожидающий в Windows Events, на CPU, чтобы он проснулся из спящего режима? - PullRequest
2 голосов
/ 16 августа 2010

Лучше всего описать мой вопрос в примере:

  1. Мы создаем дескриптор события Windows с помощью CreateEvent, с manualReset как FALSE.
  2. Мы создаем 4 потока.Убедитесь, что все они запускаются и ожидают указанное выше событие с помощью WaitForSingleObject.
  3. В основном потоке, в цикле for, мы сигнализируем это событие 4 раза с помощью SetEvent.такие как:

    for (int i = 0; i <4; ++ i) :: SetEvent (событие); </p>

Мой вопрос, можем ли мы сказатьчто все эти 4 потока наверняка будут разбужены от ожидания этого события?

Согласно моему пониманию Windows Event, ответ - ДА.Потому что, когда событие установлено, всегда есть поток, ожидающий его.

Однако я прочитал на MSDN, что " Установка события, которое уже установлено, не имеет никакого эффекта ".Поскольку ожидающие потоки, вероятно, не получат шанса на запуск во время события установки основного потока в цикле.Могут ли они все еще получать уведомления и сбрасывать событие в состояние без сигнала?Если событие не сбрасывается, следующее SetEvent в цикле явно бесполезно.

Или ядро ​​ОС знает, какой поток должен быть уведомлен, когда событие установлено, и немедленно сбрасывает это событие, если есть ожидающий поток,Таким образом, ожидающему потоку не нужно планировать сброс события в состояние без сигнала?

Любые пояснения или ссылки приветствуются.Спасибо.

Ответы [ 3 ]

1 голос
/ 16 августа 2010

Одним словом?Нет.

Нет никакой гарантии, что каждый звонок на Set() будет сигнализировать ожидающий поток.MSDN описывает это поведение следующим образом:

Нет гарантии, что каждый вызов метода Set освободит поток из EventWaitHandle, режим сброса которого - EventResetMode :: AutoReset.Если два вызова находятся слишком близко друг к другу, так что второй вызов происходит до освобождения потока, освобождается только один поток.Как будто второго звонка не произошло.Кроме того, если Set вызывается, когда нет ожидающих потоков и EventWaitHandle уже сигнализирован, вызов не имеет никакого эффекта.( Источник )

Если вы хотите обеспечить передачу определенного числа потоков, вам следует использовать более подходящий тип примитива синхронизации, такой как Семафор .

1 голос
/ 16 августа 2010

Потому что, когда событие установлено, всегда есть поток, ожидающий его.

Нет, вы этого не знаете. По какой-то причине поток может быть приостановлен на неопределенный срок непосредственно перед системным вызовом NtWaitForSingleObject.

Поскольку ожидающие потоки, вероятно, не получат шанса на запуск во время события установки основного потока в цикле.

Если поток ожидает объект, он вообще не запускается - в этом весь смысл возможности блокировки объекта синхронизации.

Могут ли они по-прежнему получать уведомления и сбрасывать событие в состояние без сигнала? Если событие не сбрасывается, следующий SetEvent в цикле явно бесполезен.

Поток, который устанавливает событие, является тем, который сбрасывает состояние сигнала обратно в 0, а не поток, который пробуждается. Конечно, если нет ожидающего потока, состояние сигнала не будет сброшено.

Или ядро ​​ОС знает, какой поток должен быть уведомлен, когда установлено событие, и немедленно сбрасывает это событие, если существует ожидающий поток.

Да, ядро ​​знает. Каждый объект диспетчера имеет список ожидания, и когда поток ожидает объекта, он помещает блок ожидания в этот список.

0 голосов
/ 16 августа 2010

Когда вы делаете SetEvent(event), так как ваш ручной сброс установлен как false для события, любой поток (окна не задает никаких предпочтений) из одного из четырех будет передан waitforsingleobject(), а при последующих вызовах другой 3 потока будут выбраны случайным образом, так как ваше событие автоматически сбрасывается после освобождения каждого потока.

Если вы пытаетесь предположить, что потоки являются повторно входящими, потоки, освобождаемые каждый раз, снова выбираются случайным образом одним из четырех по выбору ОС.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...