Чтение онлайн

на главную - закладки

Жанры

Системное программирование в среде Windows

Харт Джонсон М.

Шрифт:

hSrvrThread[iTh] = (HANDLE)_beginthreadex (NULL, 0, Server, &ThArgs[iTh], 0, &ThreadId);

 }

 /* Дождаться завершения всех потоков и "убрать мусор". */

 /* … */

 return 0;

}

static DWORD WINAPI Server(LPTHREAD_ARG pThArg)

/* Функция потока сервера.

Имеется по одному потоку для каждого
потенциального клиента. */

{

 HANDLE hCp, hTmpFile = INVALID_HANDLE_VALUE;

 HANDLE hWrEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

 DWORD nXfer, KeyIndex, ServerNumber;

 /* … */

 BOOL Success, Disconnect, Exit = FALSE;

 LPOVERLAPPED pOv;

 OVERLAPPED ovResp = {0, 0, 0, 0, hWrEvent}; /*Для ответных сообщений.*/

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

 ovResp.hEvent = (HANDLE)((DWORD)hWrEvent | 0x1);

 GetStartupInfo(&StartInfoCh);

 hCp = pThArg->hCompPort;

 ServerNumber = pThArg->ThreadNo;

 while(!ShutDown && !Exit) __try {

Success = FALSE; /* Устанавливается только в случае успешного завершения всех операций. */

Disconnect = FALSE;

GetQueuedCompletionStatus(hCp, &nXfer, &KeyIndex, &pOv, INFINITE);

if (Key [KeyIndex].Type == 0) { /* Соединение установлено. */

/* Открыть временный файл с результатами для этого соединения. */

hTmpFile = CreateFile(pThArg->TmpFileName, /* … */);

Key[KeyIndex].Type = 1;

Disconnect = !ReadFile(Key[KeyIndex].hNp, &Key[KeyIndex].Req, RQ_SIZE, &nXfer, &Key[KeyIndex].Ov) && GetLastError == ERROR_HANDLE_EOF; /* Первая операция чтения. */

if (Disconnect) continue;

Success = TRUE;

} else {

/* Чтение завершилось. Обработать запрос. */

ShutDown = ShutDown || (_tcscmp (Key[KeyIndex].Req.Record, ShutRqst) == 0);

if (ShutDown) continue;

/* Создать процесс для выполнения команды. */

/* … */ 

/* Отвечать по одной строке за один раз. На данном этапе удобно использовать функции библиотеки С для работы со строками. */

fp = _tfopen(pThArg->TmpFileName, _T("r"));

Response.Status = 0;

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

while(_fgetts(Response.Record, MAX_RQRS_LEN, fp) != NULL) {

WriteFile(Key [KeyIndex].hNp, &Response, RS_SIZE, &nXfer, &ovResp);

WaitForSingleObject(hWrEvent, INFINITE);

}

fclose(fp);

/* Уничтожить содержимое временного файла. */

SetFilePointer(hTmpFile, 0, NULL, FILE_BEGIN);

SetEndOfFile(hTmpFile);

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

Response.Status = 1;

strcpy(Response.Record, "");

WriteFile(Key[KeyIndex].hNp, &Response, RS_SIZE, &nXfer, &ovResp);

WaitForSingleObject(hWrEvent, INFINITE);

/* Конец основного командного цикла. Получить следующую команду.*/

Disconnect = !ReadFile(Key[KeyIndex].hNp, &Key[KeyIndex].Req, RQ_SIZE, &nXfer, &Key[KeyIndex].Ov) && GetLastError == ERROR_HANDLE_EOF; /* Следующее чтение */

if (Disconnect) continue;

Success = TRUE;

}

 } __finally {

if (Disconnect) {

/* Создать еще одно соединение по этому каналу. */

Key[KeyIndex].Type = 0;

DisconnectNamedPipe(Key[KeyIndex].hNp);

ConnectNamedPipe(Key[KeyIndex].hNp, &Key[KeyIndex].Ov);

}

if (!Success) {

ReportError(_T("Ошибка сервера"), 0, TRUE);

Exit = TRUE;

}

 }

 FlushFileBuffers(Key[KeyIndex].hNp);

 DisconnectNamedPipe(Key[KeyIndex].hNp);

 CloseHandle(hTmpFile);

 /* … */

 _endthreadex(0);

 return 0;

 /* Подавление предупреждающих сообщений компилятора. */

}
 

Резюме

Для выполнения асинхронных операций ввода/вывода в Windows предусмотрены три метода. Самой распространенной и наиболее простой является методика, основанная на использовании потоков, которая, в отличие от двух остальных, способна работать даже под управлением Windows 9x. Каждый из потоков отвечает за выполнение определенной последовательности действий, состоящей из одной или нескольких последовательно выполняющихся, блокирующихся операций ввода/вывода. Кроме того, каждый поток должен располагать собственным дескриптором файла или канала.

Поделиться:
Популярные книги

Усадьба леди Анны

Ром Полина
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Усадьба леди Анны

Чужая дочь

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Чужая дочь

Светлая тьма. Советник

Шмаков Алексей Семенович
6. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Светлая тьма. Советник

Двойник Короля

Скабер Артемий
1. Двойник Короля
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Двойник Короля

Его нежеланная истинная

Кушкина Милена
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Его нежеланная истинная

Последний Паладин. Том 2

Саваровский Роман
2. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 2

Измена. Наследник для дракона

Солт Елена
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Измена. Наследник для дракона

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9

Мастер темных Арканов

Карелин Сергей Витальевич
1. Мастер темных арканов
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Мастер темных Арканов

Адвокат империи

Карелин Сергей Витальевич
1. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
фэнтези
5.75
рейтинг книги
Адвокат империи

Кодекс Охотника. Книга XXI

Винокуров Юрий
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXI

Вечный. Книга II

Рокотов Алексей
2. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга II

Законы Рода. Том 3

Flow Ascold
3. Граф Берестьев
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 3

Наследник

Шимохин Дмитрий
1. Старицкий
Приключения:
исторические приключения
5.00
рейтинг книги
Наследник