Запуск обособленных дочерних процессов

Теоретический материал

Лабораторная работа должна быть реализована в системе программирования Microsoft Visual Studio (C++).

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

Создание процесса

Функция CreateProcess создает новый процесс и его первичный поток. Синтаксис функции:

Запуск обособленных дочерних процессов - student2.ru

Имя исполняемого файла можно задать в первом или втором параметре.

Параметр lpCommandLine позволяет указать полную командую строку, используемую функцией CreateProcess при создании нового процесса. Разбирая эту строку функция полагает, что первый компонент в ней представляет собой имя исполняемого файла. Если в этом имени расширение не указано, она считает его .exe.

Чаще всего параметру lpApplicationName передается значение NULL, а имя исполняемого файла содержится в параметре lpCommandLine.

lpProcessAttributes. Здесь определяются атрибуты защиты для нового приложения. Если указать NULL то система сделает это по умолчанию.

lpThreadAttributes. Здесь определяются атрибуты защиты для первого потока созданного приложением. NULL опять приводит к установке по умолчанию.

bInheritHandles. Флаг наследования от процесса, производящего запуск. Здесь наследуются дескрипторы. Унаследованные дескрипторы имеют те же значения и права доступа, что и оригиналы.

dwCreationFlags. Флаг способа создания процесса и его приоритет. Можно применять следующие флаги (перечислены не все):

CREATE_NEW_CONSOLE - новый процесс получает новую консоль вместо того, чтобы унаследовать родительскую.

CREATE_NEW_PROCESS_GROUP - создаваемый процесс - корневой процесс новой группы.

CREATE_SEPARATE_WOW_VDM - (только Windows NT): Если этот флаг установлен, новый процесс запускается в собственной Virtual DOS Machine (VDM).

CREATE_SHARED_WOW_VDM - (только Windows NT): Этот флаг указывает функции CreateProcess запустить новый процесс в разделяемой Virtual DOS Machine.

HIGH_PRIORITY_CLASS - указывает на то, что процесс выполняет критичные по времени задачи.

IDLE_PRIORITY_CLASS - указывает на то, что процесс выполняется только когда система находится в состоянии ожидания.

NORMAL_PRIORITY_CLASS - указывает на то, что процесс без каких-либо специальных требований к выполнению.

REALTIME_PRIORITY_CLASS - указывает на то, что процесс имеет наивысший возможный приоритет.

lpEnvironment. Указывает на блок среды. Если NULL, то будет использован блок среды родительского процесса. Блок среды это список переменных имя=значение в виде строк с нулевым окончанием.

lpCurrentDirectory. Указывает текущий диск и каталог. Если NULL, то будет использован диск и каталог процесса родителя.

LpStartupInfo. Используется для настройки свойств процесса, например расположения окон и заголовок. Элементы структуры STARTUPINFO задают атрибуты отображения нового процесса. Большинство приложений порождает процессы с атрибутами по умолчанию. Но и в этом случае нужно инициализировать все поля структуры STARTUPINFO хотя бы нулевыми значениями, а в поле cb занести размер этой структуры.

STARTUPINFO sti;// структура

ZeroMemory(&sti,sizeof(STARTUPINFO));// обнулить

sti.cb=sizeof(STARTUPINFO);// указать размер

lpProcessInformationСтруктура PROCESS_INFORMATION с информацией о процессе. Будет заполнена Windows.

Перед вызовом функции CreateProcess необходимо определить две структурные переменные типа STARTUPINFO и PROCESS_INFORMATION:

Запуск обособленных дочерних процессов - student2.ru

Адреса этих структур передаются в двух последних параметрах функции CreateProcess.

Если запуск нового процесса осуществлен успешно, то функция CreateProcess возвращает значение TRUE и помимо этого заполняет поля структуры PROCESS_INFORMATION, которая определена следующим образом:

Запуск обособленных дочерних процессов - student2.ru

Завершение процесса

Процесс можно завершить четырьмя способами:

· Выходная функция первичного потока, например WinMain, возвращает управление (предпочтительный способ).

· Один из потоков вызывает функцию ExitProcess.

· Поток другого процесса вызывает функцию TerminateProcess (нежелательный способ).

· Все потоки процесса завершаются по своей воле.

Запуск обособленных дочерних процессов

В большинстве случаев приложение создает другие процессы как обособленные (detached processes). Это значит, что после создания и запуска нового процесса родительскому процессу нет нужды взаимодействовать с ним или ждать, пока он закончит работу. Именно так и действует Explorer. Это приложение запускает для пользователя новые процессы, а после этого более не следит за их судьбой.

Для упорядоченного вывода результатов работы процессов (потоков) на экран можно использовать функцию Sleep():

VOID Sleep(

DWORD dwMilliseconds // время ожидания в милисекундах

);

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

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

CreateThread – создание потока:

HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId );

lpSecurityAttributes - обычно устанавливается в нуль, чтобы использовать заданные по умолчанию атрибуты защиты.

dwStackSize - размер стека. Каждый поток имеет собственный стек.

lpStartAddress - адрес памяти, где стартует поток. Он должен быть равен адресу функции (адрес функции – ее имя).

lpParameter - long 32 разрядный параметр, который передается функции нового потока.

dwCreationFlags - 32 бит переменная флагов, которая позволяет Вам управлять запуском потока (активный, приостановленный и т.д.).

lpThreadId - переменная, в которую загружается идентификатор нового потока.

Пример применения:

for (i=0;i<num;i++) {

hThread[i]=CreateThread(NULL,//атрибутов безопасности нет

0, // размер стека – по умолчанию

LPTHREAD_START_ROUTINE) unit, // функция потока

(LPVOID)i, //аргумент функции потока

0, // флаг создания – по умолчанию

&IDThread);//возвращаемый идентификатор созданного потока

if (hThread[i] == NULL)

printf("Ошибка создания потока #%d\n", i);

else

printf("Указатель %Lu потока#%d\n",hThread[i], i); }

Наши рекомендации