Приложения, процессы, потоки и окна 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Приложения, процессы, потоки и окна



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

У одного процесса может быть несколько потоков. Например, в текстовом редакторе один поток может обрабатывать ввод данных от пользователя, а другой передавать документ на принтер.

Окно всегда "принадлежит" потоку. Поток может владеть одним или несколькими окнами, а также может не иметь ни одного окна. Окна потока сами находятся в иерархической связи: некоторые из них являются окнами верхнего уровня, а некоторые – дочерними окнами других окон (рис. 1.1).

 
 

 
 

Рис. 1.1. Процессы, потоки и окна.

 

В Windows существует большое количество разных типов окон. Некоторые из них очевидны, например, главное окно приложения (о котором пользователь обычно думает, что это и есть приложение) и диалоговые окна. Менее очевидно, что большинство элементов управления в окнах приложений и диалоговых окнах тоже являются окнами. Каждая кнопка, строка ввода, полоса прокрутки, список, пиктограмма и даже фон рабочего стола рассматриваются ОС как окна.

На рис. 1.2 показан рабочий стол Windows 95 c двумя запущенными приложениями (Блокнот и Калькулятор). Каждое окно, в том числе кнопки, выделено черной рамкой (изображение получено с помощью утилиты Spy++ из комплекта Visual C++).

Рис. 1.2. Окна различных типов.

 

Оконные классы

Оконные классы – это шаблоны, хранящие информацию о свойствах окна. Среди этих свойств – начальные размеры окна, его пиктограмма, курсор и меню. Вероятно, самое главное свойство – это адрес функции, называемой оконной процедурой. Приложение обычно выполняет обработку полученных сообщений с помощью вызова функции DispatchMessage из Win API. Функция DispatchMessage, в свою очередь, вызывает соответствующую оконную процедуру. Адрес оконной процедуры при этом извлекается из оконного класса окна, которому послано сообщение. Именно оконная процедура выполняет обработку всех сообщений, посылаемых окну.

В Windows есть много стандартных оконных классов, например, стандартные элементы управления вроде кнопок (класс Button) и строк ввода (класс Edit).

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

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

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

Используемые термины похожи на термины объектно-ориентированного программирования, но отличаются от них по смыслу. Не надо путать оконный класс с понятием класса в Си++ (например, с классами библиотеки MFC). Понятие оконного класса было введено в Windows несколькими годами раньше, чем в этой ОС распространились объектно-ориентированные языки.

 

Типы сообщений

Сообщения приходят от разных источников, информируя окна о событиях на различных уровнях ОС. Действия, которые для пользователя могут выглядеть примитивными, на системном уровне могут сопровождаться большим количеством различных сообщений. В качестве примера в табл. 1.1 приведен протокол сообщений, получаемых диалоговым окном при закрытии по нажатию кнопки OK. Этот протокол получен с помощью утилиты Spy++.

Приложение может обрабатывать не все сообщения, а только некоторые. Необработанные сообщения передаются обработчику сообщений "по умолчанию" в ОС.

 

Таблица 1.1. Сообщения, посылаемые окну "О программе" приложения MS Word при закрытии окна по нажатию пользователем кнопки OK.

Символич. идентификатор Описание
WM_LBUTTONDOWN Была нажата левая кнопка мыши.
WM_PAINT Требуется перерисовать кнопку OK, т.к. она теперь нажата.
WM_LBUTTONUP Левая кнопка мыши была отпущена.
WM_PAINT Требуется перерисовать кнопку OK, т.к. она теперь отпущена.
WM_WINDOWPOSCHANGING Положение окна на экране собирается изменяться.
WM_WINDOWPOSCHANGED Положение окна на экране только что было изменено.
WM_NCACTIVATE Была активизирована область строки заголовка окна.
WM_ACTIVATE Была активизирована клиентская область окна.
WM_WINDOWPOSCHANGING Положение окна на экране собирается изменяться.
WM_KILLFOCUS У окна будет отключен фокус ввода.
WM_DESTROY Окно уничтожается.
WM_NCDESTROY Уничтожается область заголовка окна.

 

Сообщения в Windows описываются с помощью структуры MSG:

typedef struct tagMSG {

HWND hwnd; // Идентификатор окна-получателя

UINT message; // Идентификатор сообщения

WPARAM wParam; // Дополнительная информация, смысл

LPARAM lParam; // которой зависит от типа сообщения

DWORD time; // Время посылки сообщения

POINT pt; // Местоположение указателя мыши

} MSG;

Переменная hwnd – это уникальный идентификатор окна, которому было послано сообщение. У каждого окна Windows есть свой числовой идентификатор. Переменная message является идентификатором самого сообщения. Различных сообщений в Windows несколько сотен, и у каждого собственный идентификатор. Для удобства вместо численных идентификаторов используются символические (например, WM_PAINT, WM_TIMER). Они определены в стандартных заголовочных файлах Windows (в программы на Си можно включать только файл windows.h; в нем, в свою очередь, содержатся директивы #include для включения остальных файлов).

По назначению системные сообщения можно разбить на несколько групп. Имена сообщений каждой группы начинаются с одинакового префикса, например, WM для сообщений, связанных с управлением окнами или BM – для сообщений от кнопок. Набор системных сообщений не зафиксирован, новые сообщения могут добавляться по мере роста возможностей новых версий ОС.

Чаще всего используются оконные сообщения (WM_...). Эта группа настолько большая, что можно разделить ее еще на несколько категорий. Среди них – сообщения буфера обмена, мыши, клавиатуры, сообщения MDI (многодокументный интерфейс) и многие другие. Деление сообщений на категории условно, т.о. программисту легче классифицировать большой набор сообщений.

Сообщения остальных групп относятся к специфическим типам окон. Есть сообщения, определенные для строк ввода (EM), кнопок (BM), списков (LB), комбинированных списков (CB), полос прокрутки (SBM), деревьев (TVM) и др. Эти сообщения, за редким исключением, обычно обрабатываются оконной процедурой самого элемента управления и не слишком интересны для прикладного программиста.

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

 

Сообщения и многозадачность

Процессы и потоки

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

В начале работы каждый процесс обладает единственным первичным потоком. Информация о первичном потоке передается ОС в виде адреса функции. Поэтому все Windows-приложения содержат вызываемую при запуске функцию WinMain(), адрес которой и передается в качестве адреса первичного потока. Первичный поток может создать дополнительные потоки, и т.д. Потоки одного процесса имеют доступ ко всем его объектам. Такие потоки отличаются друг от друга лишь точкой входа и локальными переменными, расположенными в адресном пространстве процесса.

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

В немногопоточных ОС (например, в большинстве версий UNIX) наименьшая исполняемая системная единица называется задачей или процессом. Алгоритм диспетчеризации задач в ОС переключает эти задачи, т.о., достигается многозадачность в среде двух и более процессов. Если приложению требуется выполнить одновременно несколько действий, то это приложение необходимо разбить на несколько задач (например, с помощью системного вызова fork в UNIX). У этого подхода есть несколько серьезных недостатков: 1) задачи являются ограниченным ресурсом (большинство ОС могут управлять лишь несколькими сотнями одновременно выполняющихся задач); 2) запуск новой задачи требует много времени и системных ресурсов; 3) новая задача не имеет доступа к памяти родительского процесса.

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

 

Процессы и сообщения

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

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

Хотя на уровне ОС потоки не делятся на типы, но в библиотеке классов MFC на Си++ они называются и оформляются по разному: рабочие потоки (без окон и обработки сообщений) и потоки пользовательского интерфейса.

 

Вызовы функций Windows API

Приложение обращается к Windows при помощи так называемых системных вызовов. Они составляют интерфейс прикладного программирования (Application Programming Interfaces, API). Для программистов вместо термина "вызов" м.б. удобнее использовать термин "функция". Функции API располагаются в системных динамических библиотеках (DLL). Существуют функции для выделения памяти, управления процессами, окнами, файлами, для рисования графических примитивов и др.

Обращение к функциям API из большинства сред разработки на Си++ осуществляется очень просто, т.к. API специально спроектирован для использования в среде Си/Си++. В текст программы надо включить заголовочный файл, содержащий описания функций API (windows.h) и в процессе компоновки использовать необходимые библиотеки (Visual C++ обычно подключает их автоматически). После этого в текст программы можно включать любые обращения к API.

"Базовый" набор системных вызовов Windows можно разделить на три группы:

· функции модуля KERNEL.DLL (управление процессами, потоками, ресурсами, файлами и памятью);

· функции модуля USER.DLL (работа с пользовательским интерфейсом, например, с окнами, элементами управления, диалогами и сообщениями);

· функции модуля GDI.DLL (аппаратно-независимый графический вывод).

Windows содержит большое количество вспомогательных API. Есть отдельные API для работы с электронной почтой (MAPI), модемами (TAPI), базами данных (ODBC). Степень интеграции этих API в системное ядро различна. Например, хотя интерфейс OLE и реализован в виде набора системных динамических библиотек, но рассматривается как часть "ядра" Windows. Остальные API, например, WinSock, можно рассматривать как дополнительные.

Различие между тем, что следует считать "ядром" Windows, а что – дополнительными модулями, довольно произвольно. C точки зрения приложения практически нет разницы между функцией API из ядра, например, из модуля Kernel, и функцией, реализованной в одной из библиотек DLL.

 



Поделиться:


Последнее изменение этой страницы: 2016-08-01; просмотров: 408; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.135.183.187 (0.028 с.)