Джонсон Харт - Системное программирование в среде Windows
- Название:Системное программирование в среде Windows
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2005
- Город:Москва • Санкт-Петербург • Киев
- ISBN:5-8459-0879-5
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Джонсон Харт - Системное программирование в среде Windows краткое содержание
Эта книга посвящена вопросам разработки приложений с использованием интерфейса прикладного программирования операционных систем компании Microsoft (Windows 9х, Windows XP, Windows 2000 и Windows Server 2003). Основное внимание уделяется базовым системным службам, включая управление файловой системой, процессами и потоками, взаимодействие между процессами, сетевое программирование и синхронизацию. Рассматривается методика переноса приложений, написанных в среде Win32, в среду Win64. Подробно описываются все аспекты системы безопасности Windows и ее практического применения. Изобилие реальных примеров, доступных также и на Web-сайте книги, существенно упрощает усвоение материала.
Книга ориентирована на разработчиков и программистов, как высокой квалификации, так и начинающих, а также будет полезна для студентов соответствующих специальностей.
Системное программирование в среде Windows - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
• jobs — выводит список текущих активных задач, снабжая каждую из задач порядковым номером и идентификатором процесса. Эта команда аналогична одноименной команде UNIX.
• kill — прекращает выполнение задачи. В данной реализации используется функция TerminateProcess, которая, как ранее уже отмечалось, не обеспечивает корректного завершения задачи, сопровождающегося "уборкой мусора". Доступна также опция, позволяющая передавать управляющие сигналы консоли.
Создать дополнительные команды, позволяющие приостанавливать существующие задачи или переводить их в фоновый режим, вам будет несложно.
Поскольку выполнение оболочки, которая поддерживает список задач, может быть прекращено, она использует специфический для каждого пользователя разделяемый файл, в котором содержатся идентификаторы процессов, команды и другая необходимая информация. Благодаря этому перезапуск оболочки никак не отразится на списке задач. В одном из упражнений вам предлагается применять для хранения этой информации не временный файл, а реестр.
Реализация программы наталкивается на определенные проблемы, связанные с параллельным выполнением задач. Некоторые процессы, запущенные из командных строк различных оболочек, могут одновременно пытаться управлять задачами. Чтобы справиться с этим, функции управления задачами используют блокировки (глава 3) в файле списка задач, в результате чего пользователь может активизировать управление задачами из различных оболочек или процессов.
В полном варианте программы, находящемся на Web-сайте книги, содержится ряд дополнительных возможностей, не представленных в приводимых листингах, например, возможность получения входных данных для командной строки из файла. Программа JobDhell послужит основой для создания более общего "процессора служб" ("service processor") в главе 13 (программа 13.3). Службы NT являются фоновыми процессами, обычно — серверами, управление которыми осуществляется командами запуска, остановки, приостановки, а также другими командами.
Создание фоновых задач
Программа 6.3 реализует процессор задач, в котором пользователю предлагается ввести одну из трех возможных команд для их дальнейшего выполнения программой. В этой программе используется набор функций управления задачами, представленный программами 6.4, 6.5 и 6.6.
/* Глава 6. */
/* JobShell.с – команды управления задачами:
jobbg — Выполнить задачу в фоновом режиме.
jobs — Вывести список всех фоновых задач.
kill — Прекратить выполнение указанной задачи из семейства задач.
Существует опция, позволяющая генерировать управляющие сигналы консоли. */
#include "EvryThng.h"
#include "JobMgt.h"
int _tmain(int argc, LPTSTR argv[]) {
BOOL Exit = FALSE;
TCHAR Command[MAX_COMMAND_LINE + 10], *pc;
DWORD i, LocArgc; /* Локальный параметр argc. */
TCHAR argstr[MAX_ARG][MAX_COMMAND_LINE];
LPTSTR pArgs[MAX_ARG];
for (i = 0; i < MAX_ARG; i++) pArgs[i] = argstr[i];
/* Вывести подсказку пользователю, считать команду и выполнить ее. */
_tprintf(_Т("Управление задачами Windows\n"));
while (!Exit) {
_tprintf(_T("%s"), _T("JM$"));
_fgetts(Command, MAX_COMMAND_LINE, stdin);
pc = strchr(Command, '\n');
*pc = '\0';
/* Выполнить синтаксический разбор входных данных с целью получения командной строки для новой задачи. */
GetArgs(Command, &LocArgc, pArgs); /* См. Приложение А. */
CharLower(argstr[0]);
if(_tcscmp(argstr[0], _T("jobbg")) == 0) {
Jobbg(LocArgc, pArgs, Command);
} else if(_tcscmp(argstr[0], _T("jobs")) == 0) {
Jobs(LocArgc, pArgs, Command);
} else if(_tcscmp(argstr[0], _T("kill")) == 0) {
Kill(LocArgc, pArgs, Command);
} else if(_tcscmp(argstr[0], _T("quit")) == 0) {
Exit = TRUE;
} else _tprintf(_T("Такой команды не существует. Повторите ввод\n"));
}
return 0;
}
/* jobbg [параметры] командная строка [Параметры являются взаимоисключающими]
–с: Предоставить консоль новому процессу.
-d: Отсоединить новый процесс без предоставления ему консоли.
Если параметры не заданы, процесс разделяет консоль с jobbg. */
int Jobbg(int argc, LPTSTR argv[], LPTSTR Command) {
DWORD fCreate;
LONG JobNo;
BOOL Flags[2];
STARTUPINFO Startup;
PROCESS_INFORMATION ProcessInfo;
LPTSTR targv = SkipArg(Command);
GetStartupInfo(&StartUp);
Options(argc, argv, _T("cd"), &Flags[0], &Flags[1], NULL);
/* Пропустить также поле параметра, если он присутствует. */
if (argv[1][0] == '-') targv = SkipArg(targv);
fCreate = Flags[0] ? CREATE_NEW_CONSOLE : Flags [1] ? DETACHED_PROCESS : 0;
/* Создать приостановленную задачу/поток. Возобновить выполнение после ввода номера задачи. */
CreateProcess(NULL, targv, NULL, NULL, TRUE, fCreate | CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP, NULL, NULL, &StartUp, &ProcessInfo);
/* Создать номер задачи и ввести ID и дескриптор процесса в "базу данных" задачи. */
JobNo = GetJobNumber(&ProcessInfo, targv); /* См. "JobMgt.h" */
if (JobNo >= 0) ResumeThread(ProcessInfo.hThread);
else {
TerminateProcess(ProcessInfo.hProcess, 3);
CloseHandle(ProcessInfo.hProcess);
ReportError(_T("Ошибка: Не хватает места в списке задач."), 0, FALSE);
return 5;
}
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
_tprintf(_T(" [%d] %d\n"), JobNo, ProcessInfo.dwProcessId);
return 0;
}
/* jobs: вывод списка всех выполняющихся и остановленных задач. */
int Jobs(int argc, LPTSTR argv[], LPTSTR Command) {
if (!DisplayJobs ()) return 1; /*См. описание функций управления задачами*/
return 0;
}
/* kill [параметры] Номер задачи (JobNumber)
–b: Генерировать Ctrl-Break.
–с: Генерировать Ctrl-C.
В противном случае прекратить выполнение процесса. */
int Kill(int argc, LPTSTR argv[], LPTSTR Command) {
DWORD ProcessId, JobNumber, iJobNo;
HANDLE hProcess;
BOOL CntrlC, CntrlB, Killed;
iJobNo = Options(argc, argv, _T("bc"), &CntrlB, &CntrlC, NULL);
/* Найти ID процесса, связанного с данной задачей. */
JobNumber = _ttoi(argv [iJobNo]);
ProcessId = FindProcessId(JobNumber); /* См. описание функций управления задачами. */
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
if (hProcess == NULL) { /* ID процесса может не использоваться. */
ReportError(_T("Выполнение процесса уже прекращено.\n"), 0, FALSE);
return 2;
}
if (CntrlB) GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, ProcessId);
else if (CntrlC) GenerateConsoleCtrlEvent(CTRL_C_EVENT, ProcessId);
else TerminateProcess(hProcess, JM_EXIT_CODE);
WaitForSingleObject(hProcess, 5000);
CloseHandle(hProcess);
_tprintf(T("Задача [%d] прекращена или приостановлена \n"), JobNumber);
return 0;
}
Обратите внимание на то, как команда jobbg создает процесс в приостановленном состоянии, а затем вызывает функцию управления задачами Get JobNumber (программа 6.4) для получения номера задачи, а также регистрации задачи и процесса, который с ней связан. Если в силу каких-либо причин задача не может быть зарегистрирована, выполнение данного процесса немедленно прекращается. Обычно' генерируется корректный номер задачи, после чего выполнение основного потока возобновляется, и он может продолжать выполнение.
Читать дальшеИнтервал:
Закладка: