Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows


Сценарий 1: асинхронный вызов функций - часть 2


Пул рассчитан на частую обработку асинхронного ввода-вывода — всякий раз, когда поток помещает в очередь запрос на ввод-вывод к драйверу устройства Пока драйвер выполняет его, поток, поставивший запрос в очередь, не блокируется и мо жет заниматься другой работой. Асинхронный ввод-вывод — ключ к созданию высо коэффективных, масштабируемых приложений, так как позволяет одному потоку обрабатывать запросы от множества клиентов по мере их поступления; ему не при ходится обрабатывать их последовательно или останавливаться, ожидая завершения ввода вывода.

Но Windows накладывает одно ограничение на запросы асинхронного ввода-вы вода, если поток, послав такой запрос драйверу устройства, завершается, данный зап рос теряется н никакие потоки о его судьбе не уведомляются. В хорошо продуман ном пуле, число потоков увеличивается и уменьшается в зависимости от потребнос тей его клиентов Поэтому, если поток посылает запрос и уничтожается из-за сокра щения пула, то уничтожается и этот запрос. Как правило, это не совсем то, что хоте лось бы, и здесь нужно найти какое-то решение.

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

Чтобы передать рабочий элемент компоненту поддержки ввода-вывода, Вы може те по-прежнему пользоваться функцией QueueUserWorkltem, но в параметре dwFlags

следует указать флаг WT_EXECUTEINIOTHREAD. А обычно Вы будете указывать в этом параметре флаг WT_EXECUTEDEFAULT (0) — он заставляет систему передать рабочий элемент компоненту поддержки других операций (не связанных с вводом-выводом).

В Windows есть функции (вроде RegNotifyChangeKeyValue), которые асинхронно выполняют операции, не относящиеся к вводу-выводу. Они также требуют, чтобы вызывающий поток не завершался преждевременно. С этой целью Вы можете исполь зовать флаг WT_EXECUTETNPERSISTENTTHREAD, который заставляет поток таймера выполнять поставленную в очередь функцию обратного вызова для рабочего элемен та. Так как этот компонент существует постоянно, асинхронная операция в конечном счете обязательно будет выполнена Вы должны позаботиться о том, чтобы функция обратного вызова выполнялась быстро и не блокировала работу компонента поддер жки таймера.




Начало  Назад  Вперед