Асинхронный файловый ввод/вывод в операционной системе WINDOWS, страница 18

Изменение уровня доступа к новому дескриптору осуществляется при помощи дополнительных аргументов вызова DuplicateHandle. Помимо уровня доступа этот вызов позволяет управлять наследованием нового дескриптора. Также ему можно приказать уничтожить исходный дескриптор после того, как будет создан новый.

Закрытие файла

Когда работа с файлом завершена, его следует закрыть. Если для открытия использовался вызов CreateFilе, закрыть файл можно при помощи вызова CloseHandle.

Вызов CloseHandle можно использовать не только для того, чтобы закрывать файловые дескрипторы, Этот вызов позволяет закрыть дескрипторы любых типов.

Разновидности асинхронного ввода/вывода

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

В Windows асинхронный ввод/вывод может быть реализован с использованием нескольких разных технологий, включая:

·  ожидание завершения ввода/вывода в отдельном программном потоке;

·  перекрывающийся (не блокируемый) ввод/вывод с явным завершением;

·  перекрывающийся ввод/вывод с завершением на основе событий;

·  перекрывающийся ввод/вывод с выполнением функции завершения;

·  перекрывающийся ввод/вывод с использованием портов завершения.

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

Асинхронный ввод/вывод с использованием отдельного программного потока

Проще всего реализовать асинхронный ввод/вывод с использованием отдельного программного потока. Для этого необходимо создать новый поток, в рамках этого потока выполнить операцию ввода/вывода, используя традиционные методы, а затем сообщить о результатах основной программе.

Для обмена данными с основной программой можно использовать циклический буфер. Этот механизм несложно реализовать, однако для защиты данных, хранящихся в буфере, придется использовать специальные механизмы Windows (например, критические секции).

Инициирование операции перекрывающегося ввода/вывода

Если при обмене данными с файлом требуется использовать перекрывающийся ввод/вывод, при открытии этого файла вызову CreateFilе необходимо передать в качестве параметра флаг FILE_FLAG_OVERLAPPED, В результате все операции ввода/ вывода, связанные с этим файлом, будут выполняться в режиме перекрывающегося ввода/вывода. Если флаг FILE_FLAG_OVERLAPPED не был использован, вызовы перекрывающегося ввода/вывода использовать нельзя, Основным отличием вызовов перекрывающегося ввода/вывода является то, что значение аргумента, содержащего указатель на структуру OVERLAPPED, отличается от NULL.

Для инициирования асинхронных процедур чтения/записи файла используются традиционные вызовы ReadFile и WriteFile, однако при асинхронном вводе/ выводе в качестве одного из аргументов этим вызовам следует передать указатель на заполненную структуру OVERLAPPED. Эта структура содержит пять полей. Первые два поля зарезервированы системой для внутреннего использования, Вторые два поля содержат 64-битное смещение относительно начала файла, указывающее, в каком месте файла следует осуществить запись или чтение данных. Это означает, что вы можете осуществить чтение или запись в любом месте файла, даже если его размер превышает 4 Гбайт- Если вы работаете с сокетом, именованным каналом или устройством (например, последовательным портом), система игнорирует значение этих полей.