Работа с COM и LPT в Win32. | страница 28



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

>#include

>#include

>. . .

>HANDLE port;

>char* buf;

>OVERLAPPED ovr;

>DWORD bc;

>. . .

>port=CreateFile("COM2", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

>memset(&ovr, 0, sizeof(ovr));

>ovr.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

>ReadFile(port, buf, buf_size, &bc, &ovr);

>/* Выполняем некую полезную работу */

>if (WaitForSingleObject(ovr.hEvent,10000) == WAIT_OBJECT_0) {

> GetOverlappedResult(port, &ovr, &bc, FALSE);

>} else {

> /* Обработка ошибки */

>}

>CloseHandle(port);

>CloseHandle(ovr.hEvent);

В этом примере переменная bc, предназначенная для получения количества считанных байт, после вызова ReadFile будет равна 0, так как никакой передачи информации еще не было. После вызова GetOverlappedResult в эту переменную будет помещено число реально считанных байт.

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

Вернемся ненадолго с структуре OVERLAPPED и функциям ReadFile и WriteFile. Для дискового ввода/вывода возможно задать одновременно несколько конкурирующих операций чтения/записи. Однако для каждой такой операции необходимо использовать свою структуру OVERLAPPED. Для работы с портами нельзя задавать конкурирующие операции. Точнее можно, но только в Windows NT. Поэтому для целей совместимости лучше этого не делать.

Теперь, уже совсем кратко, еще об одной возможности, реализованной только в Windows NT. Речь идет о "тревожном вводе-выводе". Эта возможность реализуется функциями ReadFileEx, WriteFileEx и SleepEx. Суть использования данных функий такова. Вы вызываете расширенную функцию записи или чтения, которая имеет еще один параметр – адрес функции завершения. После чего, вызвав расширенную функцию засыпания, освобождаете процессор. После завершения ввода/вывода Ваша функция завершения будет вызвана системой. Причем вызвана ТОЛЬКО в том случае, если ваша программа вызвала SleepEx. Нетрудно заметить, что данный вариант работы подходит для систем с большим количеством портов и работающих в режиме ответа по требованию. Например, сервер с мультипортовым контроллером последовательного порта, к которому подключены модемы.