
- •Файловая система и файловый ввод-вывод
- •Краткие теоретические сведения
- •Разбиение на разделы
- •Определение имеющихся логических дисков
- •1.3 Получение информации о томах
- •Поиск файлов
- •1.5.1 Отложенный (асинхронный) ввод-вывод
- •1.5.2 Контроль ошибок ввода-вывода
- •Методика выполнения
- •Отчет о работе
- •Контрольные вопросы
- •Получение информации об exe-файлах ms Windows
1.5.1 Отложенный (асинхронный) ввод-вывод
Эта принципиально новая возможность введена в Win32 с появлением реальной многозадачности. При вызове функций чтения и записи данных исходные данные передаются одному из потоков (threads) операционной системы, который и осуществляет фактические обязанности по работе с устройством. Время доступа всех периферийных устройств гораздо больше доступа к ОП, и однопоточная программа, вызвавшая Read или Write, будет дожидаться окончания операции ввода-вывода. Замедление работы программы налицо.
Выход был найден в реализации отложенного (overlapped) ввода-вывода. До начала отложенного ввода-вывода инициализируются дескриптор, объект типа события (функция CreateEvent) и структура типа TOverlapped. Затем вызывается функция ReadFile или WriteFile, в которой последний параметр указывается на TOverlapped. Эта структура содержит дескриптор события Windows (event).
ОС начинает операцию (ее выполняет отдельный программный поток, скрытый от программиста ) и немедленно возвращает управление – время на ожидание не тратится.
Признак того, что операция началась и продолжается — возврат кода ERROR_IO_PENDING. Программа может выполнять следующие операторы. Событие будет установлено ОС тогда, когда ввод-вывод закончится.
Когда, по мнению программиста, ввод-ввод должен быть завершен, можно проверить это с помощью функции WaitForSingleObject (уже рассмотренной ранее в работе Синхронизация потоков).
function WaitForSingleQbject( hHandle: THandle; dwMilliseconds: DWORD;
Объект ожидания (параметр hHandle) должен быть указан в структуре TOverlapped и передан в качестве параметра в функцию ReadFile или WriteFile. Можно указать любое время ожидания, в том числе бесконечное, указав значение второго параметра равным infinite. Признаком нормального завершения служит получение кода возврата WAIT_OBJECT_0.
Пример отложенной операции чтения (использование асинхронного чтения файла):
function AsinRead (FHandle: Thandle; var Buffer; Count: Longint): Longint;
var
succ : boolean;
nb : Cardinal;
LastError : Longint;
Overlap : TOverlapped;
begin
FillChar(Overlap, SizeOf (Overlap), 0);
Overlap.hEvent := CreateEvent (nil, True, False, nil);
Result := MaxInt;
succ := ReadFile(FHandle, Buffer, Count, nb, @Overlap);
// здесь можно вставить любые операторы, которые могут быть выполнены
// до окончания ввода-вывода
//
if not succ then
begin
LastError := GetLastError;
if LastError = ERROR_IO_PENDING
then
begin
if WaitForSingleObject(Overlap.hEvent, INFINITE)= WAIT_OBJECT_0
then
GetOverlappedResult(FHandle, Overlap, nb, TRUE);
end
else
raise EAbort.Create(Format('Read failed, error %d',[LastError]));
end;
Result := nb;
CloseHandle (Overlap.hEvent);
end;
Если задан интервал ожидания завершения операции ввода в_ миллисекундах, а операция еще не за-кончена, WaitForSingleObject вернет код завершения WAIT‗TIMEOUT. Функция GetOverlappedResult возвращает в параметре nb число байтов, действительно прочитанных или записанных во время отложенной операции.