Джонсон Харт - Системное программирование в среде Windows

Тут можно читать онлайн Джонсон Харт - Системное программирование в среде Windows - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming, издательство Издательский дом Вильямс, год 2005. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Системное программирование в среде Windows
  • Автор:
  • Жанр:
  • Издательство:
    Издательский дом Вильямс
  • Год:
    2005
  • Город:
    Москва • Санкт-Петербург • Киев
  • ISBN:
    5-8459-0879-5
  • Рейтинг:
    4.22/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Джонсон Харт - Системное программирование в среде Windows краткое содержание

Системное программирование в среде Windows - описание и краткое содержание, автор Джонсон Харт, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Эта книга посвящена вопросам разработки приложений с использованием интерфейса прикладного программирования операционных систем компании Microsoft (Windows 9х, Windows XP, Windows 2000 и Windows Server 2003). Основное внимание уделяется базовым системным службам, включая управление файловой системой, процессами и потоками, взаимодействие между процессами, сетевое программирование и синхронизацию. Рассматривается методика переноса приложений, написанных в среде Win32, в среду Win64. Подробно описываются все аспекты системы безопасности Windows и ее практического применения. Изобилие реальных примеров, доступных также и на Web-сайте книги, существенно упрощает усвоение материала.

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

Системное программирование в среде Windows - читать онлайн бесплатно полную версию (весь текст целиком)

Системное программирование в среде Windows - читать книгу онлайн бесплатно, автор Джонсон Харт
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

В другом возможном варианте решения, отличающемся большей гибкостью, можно было бы закрывать дескриптор при каждом отсоединении клиента и создавать новый дескриптор для каждого нового подключения. Этот способ аналогичен тому, который использовался в случае сокетов в главе 12. Вместе с тем, имеется одна трудность, обусловленная невозможностью удаления дескрипторов из порта завершения, в результате чего использование короткоживущих дескрипторов подобного рода будет приводить к утечке ресурсов.

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

Программа 14.4. serverCP: сервер, использующий порт завершения

/* Глава 14. ServerCP. Многопоточный сервер.

Версия на основе именованного канала, пример ПОРТА ЗАВЕРШЕНИЯ.

Использование: Server [ИмяПользователя ИмяГруппы]. */

#include "EvryThng.h"

#include "ClntSrvr.h"

/* Здесь определяются сообщения запроса и ответа. */

typedef struct { /*Структуры, на которые указывают ключи портов завершения*/

HANDLE hNp; /* и которые представляют еще не выполненные операции */

REQUEST Req; /* ReadFile и ConnectNamedPipe. */

DWORD Type; /* 0 – ConnectNamedPipe; 1 – ReadFile. */

OVERLAPPED Ov;

} CP_KEY;

static CP_KEY Key[MAX_CLIENTS_CP]; /* Доступно всем потокам. */

/* … */

_tmain(int argc, LPTSTR argv[]) {

HANDLE hCp, hMonitor, hSrvrThread[MAXCLIENTS];

DWORD iNp, iTh, MonitorId, ThreadId;

THREAD_ARG ThArgs[MAX_SERVER_TH];

/*…*/

hCp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, MAX_SERVER_TH);

/* Создать перекрывающийся именованный канал для каждого потенциального */

/* клиента, добавить порт завершения и ожидать соединения. */

/* Предполагается, что максимальное количество клиентов намного */

/* превышает количество серверных потоков. */

for (iNp = 0; iNp < MAX_CLIENTS_CP; iNp++) {

memset(&Key[iNp], 0, sizeof(CP_KEY));

Key[iNp].hNp = CreateNamedPipe(SERVER_PIPE, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_READMODE_MESSAGE | PIPE_TYPE_MESSAGE | PIPE_WAIT, MAX_CLIENTS_CP, 0, 0, INFINITE, pNPSA);

CreateIoCompletionPort(Key[iNp].hNp, hCp, iNp, MAX_SERVER_TH + 2);

Key[iNp].Ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

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

}

/* Создать рабочие серверные потоки и имя временного файла для каждой из них.*/

for (iTh = 0; iTh < MAX_SERVER_TH; iTh++) {

ThArgs[iTh].hCompPort = hCp;

ThArgs[iTh].ThreadNo = iTh;

GetTempFileName(_T("."), _T("CLP"), 0, ThArgs[iTh].TmpFileName);

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

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

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Джонсон Харт читать все книги автора по порядку

Джонсон Харт - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


Отзывы читателей о книге Системное программирование в среде Windows, автор: Джонсон Харт. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x