- •Часть 2 (продолжение): Прикладное программирование в Windows
- •Глава 8. Виртуальное окно: работа с текстом
- •8.1. Оконные координаты, цвета, отображение строк
- •Кодировка rgb-значений
- •Размеры системных метрик
- •8.2. Виртуальное окно
- •Способы заполнения прямоугольной области
- •8.3. Изменение шрифтов
- •Макроимена распространенных шрифтов
- •8.4. Создание собственных шрифтов
- •Глава 9. Программирование графики
- •9.1. Логическая система координат
- •Рекомендуемый самый яркий состав цветов
- •9.2. Пиксели, линии, дуги, прямоугольники, эллипсы и секторы
- •9.3. Работа с перьями и кистями
- •Типы линий, создаваемых пером
- •9.4. Технология виртуального окна
- •9.5. Режимы отображения и области вывода
- •Текущий режим отображения (mappind mode)
- •Глава 10. Работа с панелями инструментов
- •10.1. Общие элементы управления
- •Общие элементы управления
- •10.2. Подключение и инициализация общих элементов управления
- •10.3. Работа с панелью инструментов
- •Начальные состояния кнопок панели инструментов
- •Стиль кнопки определяется (значения поля fsStyle)
- •Сообщения к панели инструментов
- •10.4. Создание растрового изображения для панели инструментов
- •10.5. Включение подсказок
- •Глава 11. Спины, ползунки и индикаторы процессов
- •11.1. Работа со спином
- •Стили «up-down control»
- •Сообщения, которые можно посылать спину
- •11.2. Создание спина с «приятельским» окном
- •11.3. Работа с ползунком
- •Значения стилей для ползунка
- •Перечень сообщений, которые можно посылать ползунку
- •Перечень нотификационных сообщения ползунка
- •11.4. Индикатор процесса
- •Управляющие сообщения индикатору
- •Глава 12. Многозадачность: процессы и потоки
- •12.1. Создание нового процесса (отдельной задачи)
- •Разрешенные значения поля dwFlags
- •12.2. Многопотоковые программы
- •12.3. Работа с несколькими потоками
- •12.4. Синхронизация процессов и потоков: семафоры
- •12.5. Обработка событий
- •Глава 13. Приемы программного управления вычислительным процессом
- •13.1. Использование функций Проводника Explorer для работы в файловой системе
- •Управляющая информация Проводника
- •Режимы обработки файлов
- •13.2. Создание собственных динамических библиотек (dll-файлов)
- •13.3. Работа с буфером обмена Clipboard
- •Функции подсистемы Clipboard
- •Свойства выделяемого блока памяти
- •Форматы и типы данных
- •Литература
Глава 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
