Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СПО от Тихомирова / Файловая_система 9 лр.doc
Скачиваний:
25
Добавлен:
08.06.2015
Размер:
126.98 Кб
Скачать

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 число байтов, действительно прочитанных или записанных во время отложенной операции.