/* Выполняются все операции чтения. Ожидать завершения события и сразу же сбросить его. События чтения и записи хранятся в массиве событий рядом друг с другом. */

 iWaits =0; /* Количество выполненных к данному моменту операций ввода/вывода. */

 while (iWaits < 2 * nRecord) {

  ic = WaitForMultipleObjects(2 * MAX_OVRLP, hEvents[0], FALSE, INFINITE) – WAIT_OBJECT_0;

  iWaits++; /* Инкрементировать счетчик выполненных операций ввода вывода.*/

  ResetEvent(hEvents[ic / MAX_OVRLP][ic % MAX_OVRLP]);

  if (ic < MAX_OVRLP) {

   /* Чтение завершено. */

   GetOverlappedResult(hInputFile, &OverLapIn[ic], &nin[ic], FALSE);

   /* Обработать запись и инициировать операцию записи. */

   CurPosIn.LowPart = OverLapIn[ic].Offset;

   CurPosIn.HighPart = OverLapIn[ic].OffsetHigh;

   CurPosOut.QuadPart = (CurPosIn.QuadPart / REC_SIZE) * UREC_SIZE;

   OverLapOut[ic].Offset = CurPosOut.LowPart;

   OverLapOut[ic].OffsetHigh = CurPosOut.HighPart;

   /* Преобразовать запись из ASCII в Unicode. */

   for (i =0; i < REC_SIZE; i++) UnRec[ic][i] = AsRec[ic][i];

   WriteFile(hOutputFile, UnRec[ic], nin[ic] * 2, &nout[ic], &OverLapOut[ic]);

   /* Подготовиться к очередному чтению, которое будет инициировано после того, как завершится начатая выше операция записи. */

   CurPosIn.QuadPart += REC_SIZE * (LONGLONG)(MAX_OVRLP);

   OverLapIn[ic].Offset = CurPosIn.LowPart;

   OverLapIn[ic].OffsetHigh = CurPosIn.HighPart;

  } else if (ic < 2 * MAX_OVRLP) { /* Операция записи завершилась. */

   /* Начать чтение. */

   ic –= MAX_OVRLP; /* Установить индекс выходного буфера. */

   if (!GetOverlappedResult (hOutputFile, &OverLapOut[ic], &nout[ic], FALSE)) ReportError(_T("Ошибка чтения."), 0, TRUE);

   CurPosIn.LowPart = OverLapIn[ic].Offset;

   CurPosIn.HighPart = OverLapIn[ic].OffsetHigh;

   if (CurPosIn.QuadPart < FileSize.QuadPart) {

    /* Начать новую операцию чтения. */

    ReadFile(hInputFile, AsRec[ic], REC_SIZE, &nin[ic], &OverLapIn[ic]);

   }

  }

 } 

 /* Закрыть все события. */

 for (ic = 0; ic < MAX_OVRLP; ic++) {

  CloseHandle(hEvents[0][ic]);

  CloseHandle(hEvents[1][ic]);

 }

 CloseHandle(hInputFile);

 CloseHandle(hOutputFile);

 return 0;

} 

Программа 14.1 способна работать только под управлением Windows NT. Средства асинхронного ввода/вывода Windows 9x не позволяют использовать дисковые файлы. В приложении В приведены результаты и комментарии, свидетельствующие о сравнительно низкой производительности программы atouOV. Как показали эксперименты, для достижения приемлемой производительности размер буфера должен составлять, по крайней мере, 32 Кбайт, но даже и в этом случае обычный синхронный ввод/вывод работает быстрее. К тому же, производительность этой программы не повышается и в условиях SMP, поскольку в данном примере, в котором обрабатываются всего лишь два файла, ЦП не является критическим ресурсом.

<p>Расширенный ввод/вывод с использованием процедуры завершения</p>
Перейти на страницу:

Похожие книги