Функция KeWaitForMultipleObjects (wdm.h)
Подпрограмма KeWaitForMultipleObjects переводит текущий поток в состояние ожидания с оповещением или ожидание, пока все объекты диспетчера не будут переведены в состояние сигнала или (необязательно) до истечения времени ожидания.
Синтаксис
NTSTATUS
KeWaitForMultipleObjects (
ULONG Count,
PVOID Object[],
WaitType,
KWAIT_REASON WaitReason,
KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
PLARGE_INTEGER Timeout,
PKWAIT_BLOCK WaitBlockArray
);
Параметры
[in] Count
Количество объектов для ожидания. Этот параметр указывает количество элементов в массиве, на который указывает параметр Object .
[in] Object
Указатель на массив указателей на объекты диспетчера (события, мьютексы, семафоры, потоки и таймеры), для которых вызывающий объект предоставляет хранилище. Массив указателей и объекты диспетчера должны находиться в непагрегированных системных памяти. Дополнительные сведения см. в подразделе "Примечания".
[in] WaitType
Тип выполняемой операции ожидания. Укажите значение WaitAll, указывая, что все указанные объекты должны достичь состояния сигнала, прежде чем будет выполнено ожидание; или WaitAny, указывающее, что любой из объектов должен достичь сигнального состояния, прежде чем ожидание будет удовлетворено.
[in] WaitReason
Причина ожидания. Драйверы должны задать это значение Executive или, если драйвер выполняет работу от имени пользователя и работает в контексте потока пользователя, — UserRequest.
[in] WaitMode
Указывает, ожидает ли вызывающий объект в KernelMode или UserMode. Драйверы среднего и самого низкого уровня должны указывать KernelMode. Если набор объектов, ожидающий включения, включает мьютекс, вызывающий объект должен указать KernelMode.
[in] Alertable
Логическое значение, указывающее, можно ли оповещать поток, пока он находится в состоянии ожидания.
[in, optional] Timeout
Указатель на значение времени ожидания, указывающее абсолютное или относительное время в 100-наносекундных единицах, в течение которого должно быть завершено ожидание.
Положительное значение указывает абсолютное время относительно 1 января 1601 г. Отрицательное значение указывает интервал относительно текущего времени. Абсолютное время истечения срока действия отслеживает любые изменения системного времени; Изменения системного времени не влияют на относительный срок действия.
Если *Timeout = 0, подпрограмма возвращается без ожидания. Если вызывающий объект предоставляет указатель NULL , подпрограмма ожидает неограниченное время, пока любой или все объекты диспетчера не будут заданы в состояние сигнала. Дополнительные сведения см. в разделе "Примечания".
[out, optional] WaitBlockArray
Указатель на выделенный вызывающим KWAIT_BLOCK массив. Если count<= THREAD_WAIT_OBJECTS, параметр WaitBlockArray может иметь значение NULL. В противном случае этот параметр должен указывать на буфер памяти с размером sizeof(KWAIT_BLOCK) * числом байтов. Подпрограмма использует этот буфер для хранения записей при выполнении операции ожидания. Буфер WaitBlockArray должен находиться в системной памяти без памяти. Дополнительные сведения см. в подразделе "Примечания".
Возвращаемое значение
KeWaitForMultipleObjects может возвращать одно из следующих значений:
Код возврата | Описание |
---|---|
STATUS_SUCCESS | Вызывающий объект указал WaitAll для параметра WaitType , а все объекты диспетчера в массиве Object были заданы в состояние сигнальной передачи. |
STATUS_ALERTED | Ожидание было прервано, чтобы доставить оповещение в вызывающий поток. |
STATUS_USER_APC | Ожидание прервано для доставки пользовательского асинхронного вызова процедур (APC) в вызывающий поток. |
STATUS_TIMEOUT | Время ожидания истекло до выполнения указанного набора условий ожидания. Это значение может быть возвращено, если указано явное значение времени ожидания, равное нулю, но указанный набор условий ожидания не может быть выполнен немедленно. |
STATUS_WAIT_0по STATUS_WAIT_63 | Вызывающий объект указал WaitAny для WaitType , а для одного из объектов диспетчера в массиве объектов задано состояние сигнала. Нижние шесть битов возвращаемого значения кодируют отсчитываемый от нуля индекс объекта, удовлетворяющего ожидания. |
STATUS_ABANDONED_WAIT_0по STATUS_ABANDONED_WAIT_63 | Вызывающий попытался дождаться мьютекса, который был оставлен. Нижние шесть бит возвращаемого значения кодируют отсчитываемый от нуля индекс мьютекса в массиве Object . |
Обратите внимание, что макрос NT_SUCCESS распознает все эти значения состояния как "успешно".
Комментарии
Каждый объект потока имеет встроенный массив блоков ожидания, которые можно использовать для ожидания одновременной установки нескольких объектов. По возможности встроенный массив блоков ожидания следует использовать в операции ожидания с несколькими ожиданиями, так как дополнительное хранилище блоков ожидания не должно быть выделено, а затем освобождено. Однако если количество объектов, для которых необходимо одновременно ждать, больше количества встроенных блоков ожидания, используйте параметр WaitBlockArray , чтобы указать альтернативный набор блоков ожидания, которые будут использоваться в операции ожидания. Драйверам требуется выделить достаточно большой буфер памяти для WaitBlockArray. Буфер не нужно инициализировать; однако она должна быть выделена из непагрегированных системных памяти. Если параметр WaitMode имеет значение UserMode, буфер WaitBlockArray не должен выделяться в локальном стеке, так как стек может быть переключен из памяти. Драйверы могут рассматривать этот буфер как непрозрачную структуру и освобождать его после возврата подпрограммы. Если параметр Count> MAXIMUM_WAIT_OBJECTS или WaitBlockArray имеет значение NULL и Count> THREAD_WAIT_OBJECTS, система выдает 0xC проверки ошибок (MAXIMUM_WAIT_OBJECTS_EXCEEDED).
Текущее состояние каждого из указанных объектов проверяется, чтобы определить, можно ли немедленно выполнить ожидание. Если на объекты выполняются необходимые побочные эффекты, возвращается соответствующее значение.
Если ожидание не может быть выполнено немедленно, либо не указано значение времени ожидания или ненулевое значение времени ожидания, текущий поток переводится в состояние ожидания и выбирается новый поток для выполнения на текущем процессоре. Если время ожидания не указано, вызывающий поток будет оставаться в состоянии ожидания до тех пор, пока не будут выполнены условия, указанные в параметрах Object и WaitType .
Если указано время ожидания , ожидание будет автоматически выполнено, если ни одно из указанных условий ожидания не будет выполнено по истечении заданного интервала.
Нулевое значение времени ожидания позволяет протестировать набор условий ожидания, условно выполняя любые побочные эффекты, если ожидание может быть немедленно удовлетворено, как при приобретении мьютекса.
Интервалы времени ожидания измеряются относительно системных часов, а точность, с которой операционная система может определить окончание интервала времени ожидания, ограничена степенью детализации системных часов. Дополнительные сведения см. в разделе Точность таймера.
Параметр Alertable определяет, когда поток может быть оповещен, и его состояние ожидания, следовательно, прервано. Дополнительные сведения см. в разделе Ожидание и APC.
Массив, на который указывает параметр Objects, должен находиться в системной памяти без памяти. Как правило, драйвер выделяет хранилище для массива Objects в локальном стеке. Массив Objects можно выделить в локальном стеке независимо от значения параметра WaitMode .
Объекты диспетчера, на которые указывают элементы в массиве Объекты, должны находиться в непагрегированных системных памяти. Если параметр WaitMode имеет значение UserMode, стек ядра можно переключить во время ожидания. Следовательно, вызывающий объект не должен пытаться передать параметры в стеке при вызове KeWaitForMultipleObjects с помощью аргумента UserMode . При выделении события в стеке необходимо задать для параметра WaitModeзначение KernelMode.
Особое внимание следует учитывать, если параметр Object , передаваемый в KeWaitForMultipleObjects , является мьютексом. Если объект диспетчера, ожидающий, является мьютексом, доставка APC будет такой же, как и для всех остальных объектов диспетчера во время ожидания. Однако после того, как KeWaitForMultipleObjects возвращает с STATUS_SUCCESS и поток фактически содержит мьютекс, доставляются только специальные APC режима ядра. Доставка всех остальных APC, как в режиме ядра, так и в пользовательском режиме, отключена. Это ограничение на доставку APC сохраняется до тех пор, пока мьютекс не будет освобожден.
Особенно важно проверка возвращаемое значение KeWaitForMultipleObjects, если параметр WaitMode имеет значение UserMode или Alertable имеет значение TRUE, так как KeWaitForMultipleObjects может возвращать раннее время с состоянием STATUS_USER_APC или STATUS_ALERTED.
Все долгосрочные ожидания, которые могут быть прерваны пользователем, должны иметь значение UserMode waits, а параметр Alertable должен иметь значение FALSE.
По возможности параметру Alertable должно быть присвоено значение FALSE , а параметру WaitMode — значение KernelMode, чтобы снизить сложность драйвера. Основным исключением из этого является то, что ожидание является долгосрочным.
Мьютекс можно рекурсивно получить только раз MINLONG. Если это ограничение превышено, подпрограмма вызывает исключение STATUS_MUTANT_LIMIT_EXCEEDED.
Вызывающие объекты KeWaitForMultipleObjects могут выполняться по адресу IRQL <= DISPATCH_LEVEL. Однако если время ожидания = NULL или *Timeout != 0, вызывающий объект должен выполняться в IRQL <= APC_LEVEL и в контексте неарбитарного потока. (Если timeout != NULL и *Timeout = 0, вызывающий объект должен выполняться в IRQL <= DISPATCH_LEVEL.)
Требования
Требование | Значение |
---|---|
Минимальная версия клиента | Доступно начиная с Windows 2000. |
Целевая платформа | Универсальное |
Верхняя часть | wdm.h (включая Wdm.h, Ntddk.h, Ntifs.h) |
Библиотека | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | См. раздел "Примечания". |
Правила соответствия DDI | HwStorPortProhibitedDIs(storport), IrpProcessingComplete(wdm), IrqlKeWaitForMultipleObjects(wdm), SpNoWait(storport) |