Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы программирования для информатиков и инженеров. Часть 2 Прикладное программирование в Windows.docx
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
603.45 Кб
Скачать

Глава 12. Многозадачность: процессы и потоки

 

В этой главе поясняется, каким образом Вы можете использовать в своих программах возможности многозадачности Windows. Здесь представлены два очень важных и взаимосвязанных раздела программирования: процессы (process) и потоки (thread). При этом основное внимание уделяется потокам.

Как уже упоминалось в главе 1, Windows поддерживает две формы многозадач­ности. Одна из них базируется на понятии процесса. Этот тип многозадачности Windows поддерживает изначально.

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

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

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

Эта глава начинается с рассмотрения процессной многозадачности, затем опи­сывается потоковая многозадачность, а в заключение – возможности синхронизации процессов и потоков.

 

12.1. Создание нового процесса (отдельной задачи)

 

Процессная многозадачность является простейшим типом многозадачности: одна программа просто запускает другую программу, как правило, не взаимодействуя с ней. В Windows один процесс может инициировать выполнение другого процесса при помощи функции API CreateProcess(), прототип которой имеет следующий вид:

 

BOOL CreateProcess(LPCSTR lpszName,

                   LPCSTR lpszComLine,

                   LPSECURITY_ATTRIBUTES lpProcAttr,

                   LPSECURITY_ATTRIBUTES lpThreadAttr,

 

 

                   BOOL   InheritAttr, DWORD How,

                   LPVOID lpEnv, LPSTR lpszDir, 

                   LPSTARTUPINFO lpStartInfo,

                   LPPROCESS_INFORMATION lpPInfo);

 

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

Строка, указатель на которую передается в параметре lpszName, должна содержать имя выполняемой программы, которое может включать полный путь к ней. Аргумен­ты командной строки задаются в буфере, указатель на который передается в lpszComLine. Однако если значение lpszName задается как NULL, первое слово в командной строке lpszComLine трактуется как имя выполняемой программы. Поэтому параметр lpszName обычно задается как NULL, а имя программы и все необходимые аргументы командной строки задаются в строке, на которую указывает lpszComLine.

Параметры lpProcAttr и lpThreadAttr используются для задания атрибутов доступа создаваемого процесса. Они могут задаваться как NULL, и в этом случае атрибуты доступа использоваться не будут. Эти атрибуты придется использовать для работы под управлением Windows XP, которая имеет развитую систему доступа.

Если параметр InheritAttr равен TRUE (не нуль), то дескрипторы, используемые в порождающем процессе, будут наследоваться в порожденном. Если этот параметр равен FALSE (нуль), дескрипторы не наследуются. (TRUE и FALSE являются макросами, определенными в стандартном файле определений Windows.h.)

По умолчанию порожденный процесс выполняется «нормально». Однако с по­мощью параметра How можно задать дополнительные атрибуты, которые оказывают влияние на создаваемый процесс. Если значение этого параметра равно 0, исполь­зуются значения атрибутов по умолчанию. В примерах данной главы используются атрибуты создания процесса, принятые в Windows по умолчанию, поэтому для этого параметра используется нулевое значение.

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

Текущее устройство и каталог для нового процесса можно задать в параметре lpszDirЕсли его значение равно NULL, то порождаемый процесс наследует текущее устройство и каталог порожденного процесса.

Параметр lpStartInfo – это указатель на структуру STARTUPINFO, которая содержит информацию о том, как будет выглядеть главное окно порождаемого процесса. Структура STARTUPINFO определяется следующим образом:

typedef struct _STARTUPINFO

   {

   DWORD cb;          // Размер  структуры STARTUPINFO

   LPSTR lpReserved;  // Должно быть NULL

   LPSTR lpDesktop;   // Имя "рабочего стола"

   LPSTR lpTitle;  // Заголовок – только для консолей)

   DWORD dwX;         // Левый  верхний  угол

   DWORD dwY;         // нового окна

   DWORD dwXSize;     // Размеры

   DWORD dwYSize;     // нового окна

   DWORD dwXCountChars; // Размеры буфера консоли

   DWORD dwYCountChars;

   DWORD dwFillAttribute;// Начальный цвет текста

   DWORD dwFlags;// Определяет активные поля

   WORD wShowWindow;// Cпособ отображения окна

   WORD cbReserved2;// Должно быть 0

   LPBYTE lpReserved2;// Должно быть NULL

   HANDLE hStdlnput;// Стандартные дескрипторы

   HANDLE hStdOutput;

   HANDLE hStdError;

   }

      STARTUPINFO;

 

Как видно из этой структуры, Windows может предоставить больше возмож­ностей для управления порождаемым процессом, чем Вам может когда-либо пона­добиться. Обычно используют значения этих полей, поддерживаемые в Windows по умолчанию. Фактически поля dwX, dwY, dwXSize, dwYSize, dwXCountChars, dwYCountChars, dwFillAtribute и dwShowWindow игнорируются, кроме тех случаев, когда они разрешены установкой соответствующих значений в поле dwFlags. Возможные значения поля dwFlags приведены в таблице 12.1.

 

Таблица 12.1