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


Авторские права

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

Здесь можно скачать бесплатно "Джонсон Харт - Системное программирование в среде Windows" в формате fb2, epub, txt, doc, pdf. Жанр: Программирование, издательство Издательский дом "Вильямс", год 2005. Так же Вы можете читать книгу онлайн без регистрации и SMS на сайте LibFox.Ru (ЛибФокс) или прочесть описание и ознакомиться с отзывами.
Джонсон Харт - Системное программирование в среде Windows
Рейтинг:
Название:
Системное программирование в среде Windows
Издательство:
Издательский дом "Вильямс"
Год:
2005
ISBN:
5-8459-0879-5
Скачать:

99Пожалуйста дождитесь своей очереди, идёт подготовка вашей ссылки для скачивания...

Скачивание начинается... Если скачивание не началось автоматически, пожалуйста нажмите на эту ссылку.

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

Как получить книгу?
Оплатили, но не знаете что делать дальше? Инструкция.

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

Описание и краткое содержание "Системное программирование в среде Windows" читать бесплатно онлайн.



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

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






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

Альтернативы портам завершенияввода/вывода

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

Эту же методику мы могли бы применить и в серверах serverSK (программа 12.2) и serverNP (программа 11.3). Все, что для этого требуется — это организовать ожидание перехода семафора в сигнальное состояние после завершения запроса на чтение, выполнение этого запроса, создание ответа и освобождение семафора перед тем, как записать ответ. Такое решение гораздо проще того, которое реализовано в примере с портом завершения ввода/вывода, приведенном в следующем разделе. Единственная проблема состоит в том, что потоков может оказаться очень много, и для каждой из них требуется собственное стековое пространство, что приведет к большому расходу виртуальной памяти. Остроту этой проблемы можно несколько ослабить, тщательно распределяя необходимые объемы стекового пространства. Упражнение 14.6 включает в себя выполнение экспериментов с альтернативным решением подобного рода, а реализация соответствующего примера находится на Web-сайте.

Существует еще одна возможность, которую можно использовать при создании масштабируемых серверов. Выборка пакетов рабочих заготовок (work items) из очереди (см. главу 10) может осуществляться с использованием ограниченного количества потоков. Поступающие рабочие заготовки могут помещаться в очередь одной или несколькими главными потоками, как показано в программе 10.5.

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

Программа 14.4 представляет видоизмененный вариант программы serverNP (программа 11.3), в котором используются порты завершения ввода/вывода. Этот сервер создает небольшой пул серверных потоков и больший пул дескрипторов перекрывающихся каналов, а также ключей завершения, по одному для каждого дескриптора. Перекрывающиеся дескрипторы присоединяются к порту завершения, а затем вызывается функция ConnectNamedPipe. Серверные потоки ожидают сигналов завершения, связанных как с подключениями клиентов, так и с операциями чтения. Когда регистрируется операция чтения, обрабатывается соответствующий клиентский запрос, и результаты возвращаются без использования порта завершения. Вместо этого серверный поток ожидает наступления события после выполнения операции записи, причем младший бит дескриптора события в структуре OVERLAPPED устанавливается в 1.

В другом возможном варианте решения, отличающемся большей гибкостью, можно было бы закрывать дескриптор при каждом отсоединении клиента и создавать новый дескриптор для каждого нового подключения. Этот способ аналогичен тому, который использовался в случае сокетов в главе 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);


На Facebook В Твиттере В Instagram В Одноклассниках Мы Вконтакте
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!

Похожие книги на "Системное программирование в среде Windows"

Книги похожие на "Системное программирование в среде Windows" читать онлайн или скачать бесплатно полные версии.


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

Все книги автора Джонсон Харт

Джонсон Харт - все книги автора в одном месте на сайте онлайн библиотеки LibFox.

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

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

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

А что Вы думаете о книге? Оставьте Ваш отзыв.