Составители:
Рубрика:
полнение запроса на ввод/вывод при помощи вызова CanselIo(), соответст-
вующая операция ввода/вывода завершается с сообщением об ошибке
ERROR_OPERATION_ABORTED (это значение можно получить при помощи
вызова GetLastError()).
В случае, если было инициировано слишком большое количество за-
просов на асинхронный ввод/вывод, функция ReadFile() может завершиться
возвратом значения ERROR_INVALID_USER_BUFFER или ER-
ROR_NOTENOUGH_MEMORY.
В некоторых ситуациях для осуществления операций перекрывающегося
ввода/вывода удобнее использовать специально предназначенные для этого
функции ReadFileEx() и WriteFileEx(). Эти функции не могут использоваться
для обычного ввода/вывода. В качестве дополнительного аргумента каждый из
этих вызовов принимает указатель на функцию, которая будет вызвана в мо-
мент завершения операции ввода/вывода:
BOOL ReadFileEx
(HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPOVERLAPPED lpOverlapped,
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
BOOL WriteFileEx
(HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPOVERLAPPED lpOverlapped,
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );…
Однако для того, чтобы произошло обращение к функции завершения,
поток, обратившийся к ReadFileEx() или WriteFileEx(), должен находиться
в «настороженном» состоянии. Чтобы перейти в настороженное состояние, не-
обходимо использовать вызовы WaitForSingleObject() или SleepEx(). Находясь
в настороженном состоянии, поток не выполняет никаких действий, а просто
ждет, когда в результате завершения операции ввода/вывода произойдет об-
ращение к функции завершения.
Все эти особенности перекрывающегося ввода/вывода несколько обеску-
раживают. Перекрывающийся ввод/вывод удобен во многих ситуациях, однако
он не настолько асинхронный, как этого хотелось бы программистам. Чтобы
реализовать действительно асинхронный ввод/вывод, следует создать отдель-
ный программный поток, в рамках которого можно использовать обычные
функции ввода/вывода. В качестве альтернативы при разработке некоторых
программ можно использовать порты завершения ввода/вывода (о них речь
пойдет чуть позже).
Если традиционная функция чтения данных в процессе осуществления
67
полнение запроса на ввод/вывод при помощи вызова CanselIo(), соответст-
вующая операция ввода/вывода завершается с сообщением об ошибке
ERROR_OPERATION_ABORTED (это значение можно получить при помощи
вызова GetLastError()).
В случае, если было инициировано слишком большое количество за-
просов на асинхронный ввод/вывод, функция ReadFile() может завершиться
возвратом значения ERROR_INVALID_USER_BUFFER или ER-
ROR_NOTENOUGH_MEMORY.
В некоторых ситуациях для осуществления операций перекрывающегося
ввода/вывода удобнее использовать специально предназначенные для этого
функции ReadFileEx() и WriteFileEx(). Эти функции не могут использоваться
для обычного ввода/вывода. В качестве дополнительного аргумента каждый из
этих вызовов принимает указатель на функцию, которая будет вызвана в мо-
мент завершения операции ввода/вывода:
BOOL ReadFileEx
(HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPOVERLAPPED lpOverlapped,
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
BOOL WriteFileEx
(HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPOVERLAPPED lpOverlapped,
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );…
Однако для того, чтобы произошло обращение к функции завершения,
поток, обратившийся к ReadFileEx() или WriteFileEx(), должен находиться
в «настороженном» состоянии. Чтобы перейти в настороженное состояние, не-
обходимо использовать вызовы WaitForSingleObject() или SleepEx(). Находясь
в настороженном состоянии, поток не выполняет никаких действий, а просто
ждет, когда в результате завершения операции ввода/вывода произойдет об-
ращение к функции завершения.
Все эти особенности перекрывающегося ввода/вывода несколько обеску-
раживают. Перекрывающийся ввод/вывод удобен во многих ситуациях, однако
он не настолько асинхронный, как этого хотелось бы программистам. Чтобы
реализовать действительно асинхронный ввод/вывод, следует создать отдель-
ный программный поток, в рамках которого можно использовать обычные
функции ввода/вывода. В качестве альтернативы при разработке некоторых
программ можно использовать порты завершения ввода/вывода (о них речь
пойдет чуть позже).
Если традиционная функция чтения данных в процессе осуществления
67
Страницы
- « первая
- ‹ предыдущая
- …
- 65
- 66
- 67
- 68
- 69
- …
- следующая ›
- последняя »
