ПРОГРАММНОЕ ПОРОЖДЕНИЕ И УНИЧТОЖЕНИЕ ПРОЦЕССОВ В WINDOWS NT

 

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

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

BOOL CreateProcess(LPCTSTR pNameModule, LPCTSTR pCommandLine,

LPSECURITY_ATTRIBUTES pProcessAttr,

LPSECURITY_ATTRIBUTES pThreadAttr, BOOL InheritFlag,

DWORD CreateFlag, LPVOID penv, LPCTSTR pCurrDir,

LPSTARTUPINFO pstartinfo,

LPROCESS_INFORMATION pProcInfo);

Здесь LPCTSTR задает дальний указатель (адрес в модели FLAT) для текстовой стороки, DWORD аналогичен LONG.

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

Параметр pNameModule является указателем на строку текста – имя файла запускаемой программы (файла с расширением .EXE), а параметр pCommandLine – указатель на текст командной строки запуска программы. С формальной стороны эти два аргумента дублируют друг друга, практически один из них.

Параметр InheritFlag используется для задания наследования объектов дочерним процессом и в настоящей работе рассматриваться не будет (будем полагать его равным FALSE).

Параметр pCurrDir относится к дополнительным возможностям функции, он задает новый каталог для запускаемого процесса, его возможности также можно не использовать и задавать его значением NULL.

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

Параметр CreateFlag задает флаги создания и кроме достаточно тонких нюансов определяет класс приоритета создаваемого процесса. Обычное значение этого флага задается константой NORMAL_PRIORITY_CLASS.

Два последних аргумента задают адреса двух специальных структур данных для создания процесса. Структура pstartinfo соответствует структуре описания сессии (сеанса) и содержит 18 полей, определяющих в первую очередь характеристики окна для создаваемого процесса. В простейшем случае все поля могут быть заполнены нулями. Структура PROCESS_INFORMATION, задаваемая адресом в последнем параметре, содержит четыре поля для возврата учетной информации из операционной системы после создания нового процесса. Описывается она следующим образом:

Typedef struct

{HANDLE hProcess;

HANDLE hThread;

DWORD dwProcessID;

DWORD dwThread;

} PROCESS_INFORMATION;

Наиболее важными в ней являются поле hProcess, возвращающее хэндл созданного процесса, и поле dwProcessID, возвращающее идентификатор (условный номер) созданного процесса.

Возвращаемое функцией CreateProcess значение типа BOOL позволяет вызывающей программе решить, удачно ли прошел запуск – удалось ли создать процесс. При создании возвращается значение TRUE, иначе – значение FALSE, численно равное нулю. Для использования рассматриваемой функции в программе на языке СИ необходимо подключение директивой #include заголовочного файла windows.h.

Пример, представленный программами Parent.cpp и Child.cpp демонстрируется простейшее использование функции создания процесса.

 

Программа Parent.cpp

#include <windows.h>

#include <stdio.h>

DWORD CreationFlags;

int main()

{ int k;

DWORD rc;

STARTUPINFO si;

PROCESS_INFORMATION pi;

printf(“Demonstration processes, Main Process\n”);

memset(&si,0,sizeof(STARTUPINFO));

si.cb=sizeof(si);

CreationFlags=NORMAL_PRIORITY_CLASS;

rc=CreateProcess(NULL,”child.exe”,NULL,NULL,FALSE,

CreationFlags,NULL,NULL,&si,&pi);

if (!rc)

{ printf(“Error in creation process, codeError=%ld\n,GetLastError());

getch();return(0);}

printf(“For Child Process:\n”);

printf(“hProcess=%d,hThread=%d,ProcessID=%ld,ThreadID=%ld,

pi.hProcess,pi.hThread,pi.dwProcessID,dwThreadID);

for (k=0;k<10;k++)

{ printf(“I am Parent...(my k=%d)\n,k); Sleep(2000);

CloseHandle(pi.hProcess);CloseHandle(pi.hThread);

Return 0);

}

программа Child.cpp

#include <stdio.h>

#include <windows.h>

int main()

{ int k;

printf(“Demonstration Process, Child Process\n);

for (k=0;k<30;k++)

{ printf(“I am Child ... (k=%d)\n\r”,k); Sleep(1000); }

return 0;

}

В конце программы полученные при создании процесса хэндлы закрываются вызовом CloseHandle(). По существу закрываются не сами хэндлы, а связанные с ним управляющие блоки (структуры описания процессов).

При построении приложений на основе нескольких процессов может возникнуть необходимость принудительно и окончательно прекратить функционирование некоторого другого процесса. Для этого в операционных системах Windows предназначена функция TerminateProcess(), имеющая следующий прототип:

BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode)

В которой аргумент hProcess задает, какой именно процесс следует завершить, а аргумент uExitCode – код завершения.

Нормальное (не принудительное) завершение процесса с кодом завершения задает функция

VOID ExitProcess(UINT uExitCode),

которую следует ставить последней в действиях программы процесса, или вместо нее использовать мобильную и независимую от операционной системы функцию exit() с аргументом – кодом завершения.

 

Задание на лабораторную работу:

1. изучить системные функции мыши для текстового режима MS Windows.

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

 

 

Лабораторная работа № 7