Изучение организации мультипрограммирования в ОС Windows: Методические рекомендации по выполнению лабораторной работы, страница 2

LPSECURITY_ATTRIBUTES    lpThreadAttributes,     //  указатель на структуру безопасности потока

BOOL     bInheritHandles,      // флаг дескриптора наследования

DWORD  dwCreationFlags,   // флаги создания процесса

LPVOID   lpEnvironment,       // указатель на блок нового окружения среды

LPCTSTR   lpCurrentDirectory,         // указатель на  текущую директорию создаваемого процесса

LPSTARTUPINFO  lpStartupInfo,    // указатель на структуру  STARTUPINFO

LPPROCESS_INFORMATION  lpProcessInformation   // указатель на структуру PROCESS_INFORMATION

).

            Возвращаемое  значение TRUE свидетельствует о том, что процесс создан нормально, FALSE – ошибка создания процесса.

            Рассмотрим параметры функции.

            Параметр lpApplicationNameопределяет имя запускаемого приложения. Если он равен NULL, то имя запускаемого модуля – это первый параметр командной строки. Если

LpApplicationName и lpCommandLine – не NULL, то первый из них специфицирует исполняемый модуль, а второй – командную строку.

Третий и четвертый аргументы определяют атрибуты доступа к процессу и потоку соответственно. Системы Windows 95/98  разграничения доступа не имеют, поэтому в них значения этих параметров, как правило, равны NULL. Для Windows NT члены структуры позволяют устанавливать дескриптор безопасности главного потока. Если bInheritHandles равен  TRUE, то процесс наследует хэндл вызывающего процесса.

Параметр dwCreationFlag является комбинацией битовых флагов. Одна группа битовых флагов устанавливает способ создания процесса, другая – флаги приоритета процесса. Детальные сведения о назначении отдельных флагов можно получить в справочной системе Windows32 API.  Параметр lpEnvironment определяет указатель на среду (окружение) нового процесса. Если его значение равно NULL, то новый процесс использует среду вызывающего процесса.

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

STARTUPINFO   info;

memset (&info,  0,  sizeof(info);

info.cb = sizeof(info);

Наконец, параметр lpProcessInformation указывает на структуру
PROCESS_INFORMATION, в которую записываются данные о созданном процессе. Структура определена следующим образом:

typedef  struct   _PROCESS_INFORMATION          {

                                                                        HANDLE     hProcess;

                                                                        HANDLE     hThread;

                                                                        DWORD      dwProcessId;

                                                                        DWORD      dwThread;

}  PROCESS_INFORMATION;

В первое поле hProcess система записывает хэндл созданного процесса, во второе – хэндл потока. Поля             dwProcessId  и dwThread будут содержать идентификаторы процесса и потока соответственно.

            Идентификаторы и хэндлы (дескрипторы) – это не одно и то же. Дескриптор нельзя передавать из процесса в процесс. Идентификатор процесса предназначен для идентификации процесса другими процессами. Его можно передавать из одного процесса в другой. Для управления процессом из другого процесса нужно обратиться к функции OpenProcess, которой передается идентификатор управляемого процесса.

            Если системный вызов  CreateProcess создает новый процесс в ходе работы приложения, то должны быть и функции завершения процесса. Обычно для завершения процесса используется функция ExitProcess( ). Её синтаксис:

VOID  ExitProcessUINT uExitCode)    // код завершения.

Единственный её параметр – код завершения. Эта функция должна завершаться изнутри процесса.

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

            BOOLTerminateProcess(HANDLE hProcess, UINT uExitCode);.

Первый параметр очевиден – это хэндл процесса, который нужно завершить, второй – идентичен рассмотренному выше параметру.

            Кроме данных функций для временной приостановки процесса используется функция VOID Sleep(DWORD dwMilliseconds) с параметром, равным времени приостановки процесса в миллисекундах.

            В Приложении 2 приведена программа, которая при выборе элемента меню “New process” создает новый процесс, в котором запускается редактор Notepad. Всего может быть запущено до 10 процессов. Командой “Killprocess” меню программы процесс уничтожается. Для создания процесса используется рассмотренная выше функция CreateProcess. Некоторая громоздкость  кода программы объясняется  типом приложения (GUI – графический интерфейс пользователя) и использованием только средств Win32 API без применения библиотек OWL или MFC в коде программы.

2.4.  Функции  создания и завершения потока

Потоки (threads) одного процесса пользуются ресурсами породившего их процесса. Если процесс обладает только одним потокам, то разницы между процессом и потоком нет. Но поток может создавать новые потоки и т.д. При правильной организации многозадачность в виде одного процесса с несколькими потоками будет более эффективной, чем в виде нескольких процессов с одним потоком. Но при ошибочной организации потоков результат может быть обратным.