Операционные системы. Учебное пособие. Марапулец Ю.В. - 136 стр.

UptoLike

Составители: 

нить операции ReadFile() и WriteFile(), значит, при этом допускается использовать пере-
крывающийся ввод/вывод.
Прежде чем вы сможете осуществлять в отношении файла операции перекрываю-
щегося ввода/вывода, необходимо открыть файл при помощи функции CreateFile() с ис-
пользованием флага FILE_FLAG_OVERLAPPED. Если этот флаг не указать, перекры-
вающийся ввод/вывод будет невозможен. Если флаг установлен, вы не сможете
использовать файл обычным способом. При обмене данными с файлом будет использо-
ваться перекрывающийся ввод/вывод.
Выполняя перекрывающийся ввод/вывод при помощи функций ReadFile() и Write-
File(), в качестве одного из аргументов вы передаете этим функциям указатель на струк-
туру OVERLAPPED. Первые два 32-битных слова этой структуры зарезервированы сис-
темой для внутреннего использования. Вторые два слова могут содержать 64-битное
смещение, указывающее на позицию файла, в которой будет осуществляться чтение или
запись данных. Ввод/вывод осуществляется асинхронно, поэтому не существует гаран-
тий, что данные из файла будут извлекаться (или записываться) последовательно байт за
байтом. Таким образом, при выполнении перекрывающегося ввода/вывода не существу-
ет понятия текущей позиции. При выполнении любой операции вы просто указываете
смещение в файле. Если вы работаете с потоками данных (например, последовательный
порт или сокет), понятие смещения теряет смысл, поэтому система игнорирует соответ-
ствующее поле структуры OVERLAPPED. Последнее поле структуры OVERLAPPED -
это дескриптор события. Впрочем, его можно не указывать (присваивать NULL).
Когда происходит обращение к функции асинхронного ввода/вывода, система мо-
жет завершить процедуру ввода/вывода немедленно. Например, вы можете приказать
системе выполнить чтение одного байта из последовательного устройства и записать
этот байт в 30-байтный буфер, ожидающий ввода. В этом случае функция ввода/вывода
завершает свою работу так, словно вы и не использовали при этом механизмов перекры-
вающегося ввода/вывода. Если функция вернула ненулевое значение, значит, операция
ввода/вывода успешно завершена, а передача данных произошла фактически точно так
же, как если бы вы не использовали перекрывающегося ввода/вывода.
Особенности асинхронного ввода/вывода проявляются в случае, если функция воз-
вращает значение FALSE. Нулевое значение, возвращенное функцией ввода/вывода, оз-
начает, что либо процедура ввода/вывода находится в стадии выполнения, либо про-
изошла какая-либо ошибка. Чтобы уточнить, чем, собственно, завершился вызов
функции, необходимо вызвать функцию GetLastError(). Если этот вызов вернул значение
ERROR_IO_PENDING, значит, запрос на ввод/вывод либо ожидает своей очереди, либо
находится в стадии выполнения. Любое другое значение означает, что произошла ошиб-
ка.
Если вы обратились к функции ввода/вывода и получили подтверждение того, что
запрос на ввод/вывод находится в процессе исполнения, рано или поздно вы захотите
узнать, когда же все-таки осуществление ввода/вывода завершится? Если вы осуществ-
ляете чтение данных, вы не сможете использовать данные из буфера чтения до того мо-
мента, пока не завершится операция чтения. Если вы осуществляете запись, рано или
поздно вы должны убедиться в том, что процедура записи успешно завершена.
Наиболее простой способ проверить текущее состояние запроса на ввод/вывод -
воспользоваться функцией GetOverlappedResult().
BOOL GetOverlappedResult( HANDLE hFile, // дескриптор файла или устройства
LPOVERLAPPED lpOverlapped, // поддержка асинхронного ввода/вывода
LPDWORD lpNumberOfBytesTransferred, // количество переданных байт
BOOL bWait ); // флаг ожидания
138
нить операции ReadFile() и WriteFile(), значит, при этом допускается использовать пере-
крывающийся ввод/вывод.
      Прежде чем вы сможете осуществлять в отношении файла операции перекрываю-
щегося ввода/вывода, необходимо открыть файл при помощи функции CreateFile() с ис-
пользованием флага FILE_FLAG_OVERLAPPED. Если этот флаг не указать, перекры-
вающийся ввод/вывод будет невозможен. Если флаг установлен, вы не сможете
использовать файл обычным способом. При обмене данными с файлом будет использо-
ваться перекрывающийся ввод/вывод.
      Выполняя перекрывающийся ввод/вывод при помощи функций ReadFile() и Write-
File(), в качестве одного из аргументов вы передаете этим функциям указатель на струк-
туру OVERLAPPED. Первые два 32-битных слова этой структуры зарезервированы сис-
темой для внутреннего использования. Вторые два слова могут содержать 64-битное
смещение, указывающее на позицию файла, в которой будет осуществляться чтение или
запись данных. Ввод/вывод осуществляется асинхронно, поэтому не существует гаран-
тий, что данные из файла будут извлекаться (или записываться) последовательно байт за
байтом. Таким образом, при выполнении перекрывающегося ввода/вывода не существу-
ет понятия текущей позиции. При выполнении любой операции вы просто указываете
смещение в файле. Если вы работаете с потоками данных (например, последовательный
порт или сокет), понятие смещения теряет смысл, поэтому система игнорирует соответ-
ствующее поле структуры OVERLAPPED. Последнее поле структуры OVERLAPPED -
это дескриптор события. Впрочем, его можно не указывать (присваивать NULL).
      Когда происходит обращение к функции асинхронного ввода/вывода, система мо-
жет завершить процедуру ввода/вывода немедленно. Например, вы можете приказать
системе выполнить чтение одного байта из последовательного устройства и записать
этот байт в 30-байтный буфер, ожидающий ввода. В этом случае функция ввода/вывода
завершает свою работу так, словно вы и не использовали при этом механизмов перекры-
вающегося ввода/вывода. Если функция вернула ненулевое значение, значит, операция
ввода/вывода успешно завершена, а передача данных произошла фактически точно так
же, как если бы вы не использовали перекрывающегося ввода/вывода.
      Особенности асинхронного ввода/вывода проявляются в случае, если функция воз-
вращает значение FALSE. Нулевое значение, возвращенное функцией ввода/вывода, оз-
начает, что либо процедура ввода/вывода находится в стадии выполнения, либо про-
изошла какая-либо ошибка. Чтобы уточнить, чем, собственно, завершился вызов
функции, необходимо вызвать функцию GetLastError(). Если этот вызов вернул значение
ERROR_IO_PENDING, значит, запрос на ввод/вывод либо ожидает своей очереди, либо
находится в стадии выполнения. Любое другое значение означает, что произошла ошиб-
ка.
      Если вы обратились к функции ввода/вывода и получили подтверждение того, что
запрос на ввод/вывод находится в процессе исполнения, рано или поздно вы захотите
узнать, когда же все-таки осуществление ввода/вывода завершится? Если вы осуществ-
ляете чтение данных, вы не сможете использовать данные из буфера чтения до того мо-
мента, пока не завершится операция чтения. Если вы осуществляете запись, рано или
поздно вы должны убедиться в том, что процедура записи успешно завершена.
      Наиболее простой способ проверить текущее состояние запроса на ввод/вывод -
воспользоваться функцией GetOverlappedResult().

BOOL GetOverlappedResult( HANDLE hFile, // дескриптор файла или устройства
           LPOVERLAPPED lpOverlapped, // поддержка асинхронного ввода/вывода
           LPDWORD lpNumberOfBytesTransferred, // количество переданных байт
           BOOL bWait );                // флаг ожидания



                                         138