Библиотека Интернет Индустрии I2R.ru |
|||
|
Асинхронный ввод/выводПредисловие Хорошо, вы должны знать, что существует два типа операций ввода/вывода - синхронный и асинхронный типы. Используя функции синхронного ввода/вывода вы будете ждать, пока операция ввода/вывода не будет закончена. Функции асинхронного ввода/вывода позволяют вам посылать запросы на выполнение операции ввода/вывода системе и немедленно продолжить выполнение кода. Когда операция асинхронного ввода/вывода будет закончена, система пошлет соответствующее уведомление. Запрос на операцию асинхронного ввода/вывода Первое, что вы должны сделать при работе с любым видом устройств - это открыть его с помощью CreateFile, задав флаг FILE_FLAG_OVERLAPPEd. Сделав это, мы можем использовать ReadFile и WriteFile.
Структура OVERLAPPED - эта структура используется только для асинхронного ввода/вывода.
Прежде чем вызывать некоторые функции API ввода/вывода, некоторые поля данной структуры должны быть инициализированы. указатель на количество записанных байтов - содержит количество прочтенных или записанных байтов. Я думаю, что назначение других параметров достаточно ясно. Получение результатов асинхронной операции После запроса на выполенение операции мы делаем все, что хотим, но по прошествии некоторого времени нам, вероятно, понадобятся результаты операции ввода/вывода. Для этого есть четыре пути:
Я сказал, что есть четыре пути, а упомянул только три... :))) Хорошо, последний называется 'completion ports'. Он, как правило, используется серверами, поэтому я не буду тратить на него время... говоря словами J.R.Cimrman'а: "Вы можете говорить об этом, вы можете не соглашаться, но это все, что вы можете сделать..." А теперь - в путь! Сигнализация объектов устройств ядра Каждый хэндл устройства система считает синхронизационным объектом. Вызов функции ReadFile или WriteFile устанавливает хэндл устройства в несигнализирующее значение. После того, как асинронная операция ввода/вывода выполнена, хэндл устройства переход в значение сигнализирование. Поэтому мы можем подождать конца асинхронной операции ввода/вывода с помощью WaitForSingleObject или WaitForMultipleObject.
время ожидания - период времени, в течении которого функция ждет сигнализации
булевое значение - установка в TRUE(1) заставит функцию ждать все хэндлы, в противном случае функция возвратится после сигнализации одного хэндла возвраты этих функций:
После вызова одной из этих функций мы значем, что операция ввода/вывода была завершена, однако мы не знаем ее результат. Чтобы узнать его, существует функция GetOverlappedResult.
булевое значение - ожидание - если TRUE(1), тогда функция будет ждать, пока не будет выполнена операция асинхронного ввода/вывода, иначе она возвратится немедленно, поэтому мы можем для сигнализации использовать эту функцию вместо функций WaitFor'x'Objects. возвраты - мы получаем булевое значение - мы должны вызвать GetLastError, чтобы проверить результат операции. Прерываемый ввод/вывод Чтобы понять прерываемый ввод/вывод, вы должны знать, что существует очередь APC. APC расшифровывается как асинхронный вызов процедуры. APC создается для каждого треда. Мы должны послать запрос на асинхронную операцию ввода/вывода и сохранить ее результаты в APC. Чтобы сделать это, мы должны использовать функцию ReadFileEx или WriteFileEx. У этих практически те же параметры, что и у их аналогов без приставки 'Ex'. Основное изменение состоит в том, что необходимо указать функцию обратного вызова. Итак, я упомянул функции ReadFileEx и WriteFileEx.
Прототип функции обратного вызова (определение взято из MSDN).
Я думаю, что назначение параметров достаточно ясно...хех. И немного о прерываемом состоянии. Тред находится в прерваемом состоянии, если он вызвал одну из пяти функций:
(смотри прототипы в конце каждой части статьи) Последний параметр первых четырех функций - это булевое значение, которое устанавливает, является ли спящий тред прерываемым. В последней функции вы должны установить флаги на MWMO_ALERTABLE. И, наконец, заключительные слова данной части. Вы запрашиваете выполнение операции асинхронного ввода/вывода с помощью функций ReadFileEx или WriteFileEx, затем вы делаете еще что-нибудь. Когда вам нужно получить результаты операции, вы должны вызвать какую-нибудь API-функцию, чтобы установить тред в прерываемое состояние и если в APC находится выполненная операция ввода/вывода, будет вызывана функция обратного возврата. Вот и все... Прототипы, которые я обещал...
Дополнение Есть еще одна функция, которую следует обсудить. Это QueueUserAPC. Она позволяет установить новую запись в APC. У этой функции следующий прототип:
У функции обратного вызова следующий прототип (взят из MSDN):
Параметр хэндла треда может указывать на тред, в другом процессе, а не в том, который вызывает. Последний параметр QueueUserAPC шлется как параметр функции обратного вызова. Поэтому, возможно, эта функция может быть использована для какого-нибудь IPC, в любом случае, у нее только один 32-х битный параметр... Событийная сигнализация Чтобы понять событийную сигнализацию, вам нужно быть знакомым с событиями. Если нет, вы, вероятно, не поймет следующие слова. Как бы то ни было, я оставляю это на вас. Хорошо, если вы взглянете на структуру OVERLAPPED, вы увидите двойное слво под названием _eventHandle. Он заполнено хэндлом события. Поэтому вы заполняете это поле хэндлом события, а затем запрашиваете операцию асинхронного ввода/вывода. Затем, если вы хотите получить результат вашей операции ввода/вывоа, вы просто ждете его с помощью какой-нибудь соответствующей функции (например, WaitForSingleObject). Эта и другие необходимые функции объяснены где-то в этой статье, поэтому я больше не буду этого касаться. И, напоследок, заключительные слова: наслажайтесь событийной сигнализацией :). mort[MATRiX], пер. Aquila |
|
2000-2008 г. Все авторские права соблюдены. |
|