Управление процессами и памятью в Linux

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

Объект СОМ имеет право называться фабрикой класса, если он поддерживает интерфейс IClassFactory. В нем реализованы всего два метода:

CoCreateInstance – создает новый экземпляр класса. Все необходимые параметры, кроме IID, метод получает от фабрики класса. В этом его отличие от одноименного общего метода библиотеки;

LockServer – оставляет сервер функционировать после создания объекта.

 

Библиотека типов.

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

Для создания библиотеки типов при помощи операторов IDL, используются специальные компиляторы. Доступ к библиотеке осуществляется по CLSID класса объекта. Кроме того, библиотека имеет собственный GUID, который сохраняется в системном реестре при регистрации объекта.

Каждая библиотека типов имеет интерфейс ITypeLib, который работает с ней как с единым объектом. Для достепа к информации об отдельном интерфейсе используется интерфейс ITypeInfo. Для доступа к библиотеке по GUID используется общий метод LoadRegTypeLib. Если клиенту известно имя файла библиотеки, то можно воспользоваться методом LoadTypeLib.

Расширение COM-технологии посредством службы, обеспечивающей создание COM-объектов для совместного использования многими клиентами, авторизованный доступ к этим объектам, а при необходимости также обработку транзакций этими объектами. Расширенная таким образом технология COM стала именоваться COM+, а сам сервис, реализующий это расширение и являющийся составной частью Windows 2000, получил название Microsoft Component Services (службы компонентов).

Службы компонентов обеспечивают централизацию использования серверов автоматизации, совместное использование многими клиентами пула COM-объектов и ресурсов (в частности, соединений с базой данных), а также управление транзакциями. Отметим, что, помимо создания COM-объектов для коллективного пользования, предоставления сервисов авторизации пользователя при доступе к объектам и обработки транзакций, службы компонентов предоставляют средства мониторинга объектов и транзакций.

Рассмотрим типичный сценарий работы приложения, использующего службы компонентов (MCS). Пользователь запускает клиентское приложение, реализованное в виде исполняемого файла или Web-приложения. Клиентское приложение пытается установить соединение с объектом COM+. Если компонент COM+, содержащий такой объект, реализован в виде внутрипроцессного сервера, этот объект может выполняться в адресном пространстве приложения dllhost.exe или в адресном пространстве клиентского приложения. (Если речь идет о Windows NT и Microsoft Transaction Server, то компонент, содержащий такой объект, обязательно должен быть реализован во внутрипроцессном сервере, а выполняется он в адресном пространстве приложения mtx.exe; объект MTS также может выполняться и в адресном пространстве клиентского приложения). В общем случае в объекте COM+ может быть реализована практически любая функциональность, например такой объект вполне может быть сервером доступа к данным.

Если запрос на установку соединения корректен, то в адресном пространстве того приложения, в котором должен функционировать объект, создается так называемый контекст объекта (если при этом приложение dllhost.exe не запущено, происходит его запуск). Контекст объекта содержит такие дополнительные сведения, которые не предусмотрены спецификацией COM и потому не содержатся в COM-объектах, — это правила доступа к объекту и способ участия его в транзакциях. Контекст создается для каждого клиента, обслуживает именно его (в отличие от, собственно, COM-объекта) и «по поручению» клиента взаимодействует с COM-объектом, который может быть и только что созданным, и взятым из имеющегося пула объектов.

После создания контекста клиентское приложение может посылать объекту COM+ запросы на выполнение его методов. Эти методы могут, например, выполнять запросы к СУБД или реализовывать какие-то иные действия, в том числе обращаться к другому объекту COM+ (в последнем случае мы можем говорить о «родительских» и «дочерних» объектах).

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

Если же метод объекта COM+ успешно завершил свою работу (неважно, с помощью дочерних объектов или без таковой), он информирует об этом службы компонентов, равно как и о том, что данный клиент в нем больше не нуждается. Затем данный объект может быть разрушен, возвращен в пул или использован другим клиентом.

 

Требования к объектам COM+

Объекты COM+ являются серверами автоматизации и, как и другие подобные серверы, реализуют интерфейс IDispatch. Все объекты COM+ поддерживают специфический для них интерфейс IObjectControl, содержащий методы для активации и деактивации объекта COM+ и управления ресурсами, в том числе соединениями с базами данных.

Серверный объект COM+ должен иметь стандартную фабрику классов и библиотеку типов (и та и другая автоматически создаются при использовании эксперта Transactional Object wizard). Помимо этого компонент должен, как и все внутрипроцессные серверы автоматизации, экспортировать функцию DllRegisterServer и осуществлять автоматическую регистрацию его CLSID (эксперт Transactional Object wizard автоматически генерирует соответствующий код).

Если предполагается коллективное использование серверного объекта, он должен не хранить внутри себя сведения о состоянии данных, связанных с конкретным клиентом (например, результаты запросов, номера текущей записи в наборе данных и т.д.), а немедленно пересылать такие сведения клиентскому приложению. Объекты, удовлетворяющие этому требованию, обозначаются термином «не хранящие состояние» (stateless objects).

В общем случае при создании кода объектов COM+ рекомендуется пользоваться соединением с базой данных минимальное время и как можно быстрее вернуть его в соответствующий пул ресурсов. Ссылка же на контекст объекта при этом может сохраняться достаточно долго. По этой же причине рекомендуется также вызывать метод SetComplete как можно чаще, чтобы как можно быстрее вернуть объект в соответствующий пул объектов.

 

Особенности управления объектами COM+

Объекты COM+ объединяются в приложения COM+ — Applications (в MTS они назывались; «пакетами» — packages), каждый из которых может содержать один или несколько объектов. Управление объектами и приложениями COM+ осуществляется с помощью приложения Componet Services Explorer, которое доступно в разделе Administrative Tools панели управления Windows 2000.

Каждый объект, зарегистрированный как объект COM+, обладает свойством Transaction Support, определяющим правила участия объекта в транзакциях. Это свойство принимает пять возможных значений:

Disabled — для данного объекта не создается контекст транзакции;

Not Supported — службы Component Services не запускают компонент внутри контекста транзакции;

Supported — службы Component Services запускают компонент внутри контекста транзакции, если таковая запрошена, в противном случае — вне контекста;

Required — службы Component Services помещают объект в контекст транзакции при вызове любого из методов. Если для этого объекта транзакция недоступна, инициируется новая;

Requires new — службы Component Services инициирует новую транзакцию при создании объекта независимо от того, какие транзакции в этот момент выполняются.

При реализации механизма обработки событий, возникающих в объектах, в отличие от событий COM, где за уведомлением клиентов следит сам сервер, в COM+ за событиями и уведомлением следят службы компонентов. При этом для генерации событий создается отдельный объект-издатель, к которому производится обращение в момент наступления события. Затем службы компонентов обращаются ко всем клиентам, подписанным на это событие (они содержат объекты-подписчики).

Объекты-издатели не должны содержать реализации своих интерфейсов — она содержится не в серверном объекте, а в клиентском приложении (в подписчике на данное событие). Поэтому после описания интерфейсов компонент компилируется и регистрируется в службах компонентов. При наступлении события в объекте COM+ следует инициировать создание объекта-издателя и вызвать метод, соответствующий данному событию. В объекте-подписчике (это обычный COM-объект), как правило, реализуется интерфейс объекта-издателя, а также методы этого интерфейса (в данном случае реализация методов), которые играют роль обработчиков событий, генерируемых объектом-издателем. Отметим, что и объект-издатель, и объект-подписчик должны быть зарегистрированы в одном и том же приложении COM+.

 

Управление процессами и памятью в Linux

 

 

1. Процессы в Linux и Unix

 

Для описания состояний процессов используется модель трех состояний. Модель состоит из:

1. состояния выполнения

2. состояния ожидания

3. состояния готовности

Выполнение – это активное состояние, во время которого процесс обладает всеми необходимыми ему ресурсами. В этом состоянии процесс непосредственно выполняется процессором.

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

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

Из состояния готовности процесс может перейти только в состояние выполнения. В состоянии выполнения может находиться только один процесс на один процессор.

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

Планировщик следит за временем выполнения первого процесса, если "время вышло", планировщик переводит процесс 1 в состояние готовности, а процесс 2 - в состояние выполнения. Затем, когда, время отведенное, на выполнение процесса 2, закончится, процесс 2 перейдет в состояние готовности, а процесс 3 - в состояние выполнения.

Более сложная модель – это модель, состоящая из пяти состояний. В этой модели появилось два дополнительных состояния: рождение процесса и смерть процесса. Рождение процесса – это пассивное состояние, когда самого процесса еще нет, но уже готова структура для появления процесса. Смерть процесса – самого процесса уже нет, но может случиться, что его структура, осталась в списке процессов. Такие процессы называются зомби.

Диаграмма модели пяти состояний представлена на рисунке.

Рисунок. Модель пяти состояний

 

Над процессами можно производить следующие операции:

1. Создание процесса – это переход из состояния рождения в состояние готовности

2. Уничтожение процесса – это переход из состояния выполнения в состояние смерти

3. Восстановление процесса – переход из состояния готовности в состояние выполнения

4. Изменение приоритета процесса – переход из выполнения в готовность

5. Блокирование процесса – переход в состояние ожидания из состояния выполнения

6. Пробуждение процесса – переход из состояния ожидания в состояние готовности

7. Запуск процесса (или его выбор) – переход из состояния готовности в состояние выполнения

Для создания процесса операционной системе нужно:

1. Присвоить процессу имя

2. Добавить информацию о процессе в список процессов

3. Определить приоритет процесса

4. Сформировать блок управления процессом

5. Предоставить процессу нужные ему ресурсы

 

Команда, которая позволяет получить информацию о процессе, называется ps(1) – это сокращение от "process status" (англ. – состояние процесса). После выполнения команда ps возвращает результат (например):

 

PID TTY TIME CMD

2241 ttyp4 00:00:00 bash

2346 ttyp4 00:00:00 ps

 

Команда ps выдает список процессов, выполняющихся на текущем терминале. Видно, в последнем столбце имя, при помощи которого был запущен процесс. "ps" появляется в этом списке, так как эта команда выполнялась, когда выводился список выполняющихся процессов.

PID – Process IDentifier (англ. – идентификатор процесса). pid – уникальное положительное число, которое присваивается каждому выполняющемуся процессу. Если выполнение процесса завершилось, его pid может быть использован заново, однако гарантируется, что во время выполнения процесса, его pid остается неизменным.

Можно получить список всех процессов, запущенных на машине:

ps –e

 

Чтобы было удобнее анализировать этот список, можно перенаправить вывод в файл ps.log:

 

ps -e > ps.log

 

Количество и состав процессов в списке зависит от конфигурации системы, однако есть несколько процессов, присутствующих на всех машинах. Вне зависимости от конфигурации процесс с pid равным 1 – это всегда "init", прародитель всех процессов. Он имеет первый pid, так как это первый процесс, запускаемый операционной системой. Также можно легко заметить наличие множества процессов с именами, заканчивающимися на "d" – это так называемые "демоны" – одни из самых важных процессов в системе.

 

При написании многозадачного кода в Linux используется стандартная библиотека C (libc, реализованная в Linux в glibc) и возможности системы Unix System V. Unix System V (далее SysV) – коммерческая реализация Unix, породившая одно из двух самых важных семейтв Unix, второе – BSD Unix.

В libc тип pid_t определен как целое, способное вместить в себе pid. Впредь мы будем использовать этот тип для работы с pid, однако это нужно только для ясности: использование целого типа дало бы тот же результат.

Рассмотрим функцию, которая сообщает нам pid процесса, содержащего программу

 

pid_t getpid (void)

 

и напишем программу, которая выведет в стандартный вывод свой pid. При помощи любого редактора напишите следующий код

 

--------------------------------------------------------------

#include <unistd.h>

#include <sys/types.h>

#include <stdio.h>

 

int main()

{

pid_t pid;

 

pid = getpid();

printf("pid присвоенный процессу - %d\n", pid);

 

return 0;

}

--------------------------------------------------------------

 

Программу необходимо сохранить в print_pid.c и затем скомпилировать:

 

gcc -Wall -o print_pid print_pid.c

 

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

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

 

pid_t fork(void)

 

При ее вызове происходит разветвление выполнения процесса, отчего и происходит название функции (to fork, англ. – ветвиться). Число, которое она возвращает – это pid, однако тут надо обратить внимание на то, что текущий процесс дублируется в родительском и дочернем, которые будут выполняться, чередуясь с другими выполняющимися процессами, производя различные действия. Но какой процесс будет выполняться сразу после создания копии: родительский или дочерний? Ответ: один из двух. Решение, какой процесс должен выполняться, принимается частью операционной системы, которая называется планировщиком, и она не принимает во внимание, является процесс родительским или дочерним, работая по алгоритму, основанному на других параметрах.

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

- РАЗВЕТВИТЬ

- ЕСЛИ ТЫ ДОЧЕРНИЙ ПРОЦЕСС ВЫПОЛНИТЬ (...)

- ЕСЛИ ТЫ РОДИТЕЛЬСКИЙ ПРОЦЕСС ВЫПОЛНИТЬ (...), –

который представляет собой код программы, написанный на некотором метаязыке. Причем известно, что функция fork возвращает '0' в дочерний процесс и pid дочернего процесса в родительский. Поэтому достаточно сверить возвращенный pid с нулем, и мы будем знать, какой процесс выполняет этот код. На языке C это выглядит следующим образом:

 

int main()

{

pid_t pid;

 

pid = fork();

if (pid == 0)

{

КОД ДОЧЕРНЕГО ПРОЦЕССА

}

КОД РОДИТЕЛЬСКОГО ПРОЦЕССА

}

 








Дата добавления: 2015-03-26; просмотров: 598;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.036 сек.