Сигнализация объекта ядра, управляющего событиями

октября 12 2009 by admin in Обязательный материал

Рассмотренный метод получения уведомления о завершении ввода-вывода прост, но не очень эффективен, так как не позволяет полноценно обрабатывать несколько запросов ввода-вывода. Допустим, вы пытаетесь одновременно выполнить несколько асинхронных операций с одним файлом. Скажем, вы хотите одновременно считать 10 байт и записать 10 байт.
Вы не можете синхронизировать свой поток путем ожидания сигнала, так как объект перейдет в сигнальное состояние по завершении любой из двух операций. Если вы вызываете функцию WaitForSingleObject, передавая ей описатель устройства, и она возвращает управление, вы не сможете сказать, почему это произошло: потому что завершилось чтение, запись или обе операции. Очевидно, чтобы не столкнуться с такой ситуацией, нужно иметь более подходящий способ выполнения нескольких одновременных асинхронных операций ввода-вывода. К счастью, такой способ есть.
Последний элемент структуры OVERLAPPED — hEvent — определяет объект ядра, управляющий событиями. Этот объект должен быть создан вызовом CreateEvent. Когда запрос асинхронного ввода-вывода завершается, драйвер устройства проверяет, имеет ли элемент hEvent структуры OVERLAPPED значение NULL. Если нет, драйвер инициирует событие, вызывая функцию SetEvent. Драйвер также переводит объект устройства в сигнальное состояние, как было описано выше. Между тем, если для определения завершения операции вы используете события, вам не нужно ждать, когда объект устройства перейдет в сигнальное состояние, а достаточно дождаться возникновения события.