Шаг 293.
Модели потоков. Прерывание ожидания по запросу

    На этом шаге мы рассмотрим синтаксис этих функций.

    Windows поддерживает асинхронные вызовы процедур (Asynchronous Procedure Calls, APC). При создании каждого потока с ним ассоциируется очередь асинхронных вызовов процедур (APC queue). Операционная система (или приложение пользователя при помощи функции QueueUserAPC) может помещать в нее запросы на выполнение функций в контексте этого потока. Такие функции нельзя выполнить немедленно, поскольку поток может быть занят. Поэтому операционная система вызывает их, когда поток обращается к одной из следующих функций ожидания:

function SleepEx(
  dwMilliseconds: DWORD; 
  // Период ожидания
  bAlertable: BOOL
  // Задает, должна ли функция возвращать
  // управление в случае запроса 
  // на асинхронный вызов процедуры
): DWORD; stdcall;

function WaitForSingleObjectEx(
  hHandle: THandle;
  // Идентификатор объекта
  dwMilliseconds: DWORD;
  // Период ожидания
  bAlertable: BOOL
  // Задает, должна ли функция возвращать
  // управление в случае запроса 
  // на асинхронный вызов процедуры
): DWORD; stdcall;

function WaitForMultipleObjectsEx(
  nCount: DWORD;
  // Количество объектов
  lpHandles: PWOHandleArray;
  // Адрес массива идентификаторов объектов
  bWaitAll: BOOL;           
  // Необходимость ожидания всех или любого из объектов
  dwMilliseconds: DWORD;
  // Период ожидания
  bAlertable: BOOL
  // Задает, должна ли функция возвращать
  // управление в случае запроса 
  // на асинхронный вызов процедуры
): DWORD; stdcall;

function SignalObjectAndWait(
  hObjectToSignal: THandle;
  // Объект, который будет переведен 
  // в сигнальное состояние 
  hObjectToWaitOn: THandle;
  // Объект, которого ожидает функция
  dwMilliseconds: DWORD;  
  // Период ожидания
  bAlertable: BOOL
  // Задает, должна ли функция возвращать
  // управление в случае запроса 
  // на асинхронный вызов процедуры
): DWORD; stdcall;

function MsgWaitForMultipleObjectsEx(
nCount: DWORD;
  // Количество объектов синхронизации
  var pHandles;
  // Адрес массива объектов
  fWaitAll: BOOL;  
  // Необходимость ожидания всех или любого из объектов
  dwMilliseconds, 
  // Период ожидания
  dwWakeMask: DWORD,
  // Тип события, прерывающего ожидание
  dwFlags: DWORD
  // Дополнительные флаги
): DWORD; stdcall;

    Если параметр bAlertable равен True (либо параметр dwFlags в функции MsgWaitForMultipleObjectsEx содержит значение MWMO_ALERTABLE), то при появлении в очереди АРС запроса на асинхронный вызов процедуры операционная система выполняет вызовы всех имеющихся в очереди процедур, после чего функция возвращает значение WAIT_IO_COMPLETION.

    Такой механизм позволяет реализовать, например, асинхронный ввод-вывод. Поток может инициировать фоновое выполнение одной или нескольких операций ввода-вывода функциями ReadFileEx или WriteFileEx, передав им адреса функций-обработчиков завершения операции. По завершении вызовы этих функций будут поставлены в очередь асинхронного вызова процедур. В свою очередь, инициировавший операции поток, когда он будет готов обработать результаты, может, используя одну из вышеприведенных функций ожидания, позволить операционной системе вызвать функции-обработчики. Поскольку очередь АРС реализована на уровне ядра операционной системы, она более эффективна, чем очередь сообщений, и позволяет реализовать гораздо более эффективный ввод-вывод.

    Со следующего шага мы начнем рассматривать объекты синхронизации.




Предыдущий шаг Содержание Следующий шаг