Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
методичка ПП.pdf
Скачиваний:
10
Добавлен:
02.06.2015
Размер:
288.49 Кб
Скачать

3.1. Общие сведения

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

Список всех процессов, существующих в данный момент в системе, можно получить с помощью команды ps. Эта команда может иметь несколько параметров, которые могут задаваться вместе или по отдельности. В зависимости от состава параметров выдаваемая командой ps информация может быть полной, частичной, относится ко всем процессам или только к определенным. Основные параметры команды: а - выдать информацию о процессах, запущенных со всех терминалов(если параметр опущен, то выводятся только процессы данного пользователя); r - выдать информацию только об активных или готовых к выполнению процессах; l - выдать полную информацию о процессах.

Сокращенная информация о процессе включает в себя следующие данные: PID - идентификатор процесса; TTY - символическое имя управляющего терминала (если указано имя соn, то процесс управляется системным терминалом, знак ? означает, что управляющий терминал у процесса отсутствует); STAT - состояние процесса; TIME - общее время, затраченное процессором на выполнение процесса в формате “минуты и секунды”; COMMAND - имя команды или программы, выполняемой процессом.

Команда ps фиксирует следующие состояния процесса: R - процесс выполняется или готов к выполнению; S - процесс ожидает события(сигнала, сообщения, открытия семафора); D - процесс ожидает системного ресурса (например, памяти или окончания обмена с диском); Т - процесс трассируется с помощью отладчика; Z - процесс завершен и ожидает уничтожения. Если процесс, находясь в каком-либо состоянии, будет выгружен на диск, то такое состояние помечается дополнительным символом W.

Полная информация о процессе, кроме перечисленных выше данных, содержит также следующие характеристики: F - внутренний флаг, хранящийся в дескрипторе и уточняющий состояние процесса(в данной версии не используется); UID - идентификатор пользователя; PPID - идентификатор процесса предка; PRI - системная составляющая приоритета процесса(чем больше число, тем меньше приоритет), динамически меняется в диапазоне от 1 до 30 (для процессов пользователя от 15 до 30); NI - пользовательская составляющая приоритета процесса, которая указывает, насколько надо изменить системную составляющую приоритета процесса при его запуске (может изменяться командой nice); SIZE - размер образа(код+данные+стек) процесса в килобайтах; RSS - общий объем физической памяти в килобайтах, занимаемой процессом; WCHAN - 16ричное число,указывающее, какую функцию выполняло ядро, когда процесс перешел в состояние S.

10 - -

Команда ps выдает информацию о процессах на момент своего запуска. Чтобы проследить динамику выполнения процессов можно воспользоваться командой top, которая выдает полную информацию о процессах и обновляет ее через каждые 5 с.

Для порождения процесса и получения его характеристик используются следующие функции:

int fork( ) - порождение процесса. Функция возвращает предку идентификатор потомка, а потомку - 0.

int getpid( ) - возвращает идентификатор текущего процесса;

int getppid( ) - возвращает идентификатор предка текущего процесса;

int execl ( char* name, char* arg0, char* arg1, . . . , char* argn, (char*)0) и int execv ( char* name, char* argv[ ] ) - переход к выполнению программы, находящейся в файле, имя которого указано в параметре name. Аргументы arg0 . . . argn, указанные в функциях, передаются в вызывающую программу как параметры функции main и являются указателями на строки символов;

int getuid( )- возвращает реальный пользовательский идентификатор;

int geteuid( ) - возвращает эффективный пользовательский идентификатор; int getgid( ) - возвращает реальный групповой идентификатор пользователя;

int getegid( ) - возвращает эффективный групповой идентификатор пользователя; int getpgrp( ) - возвращает идентификатор группы, к которой принадлежит процесс.

3.2. Подготовка к работе

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

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

11 - -

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

3.3. Порядок выполнения работы

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

2.Запустить команду top и наблюдать изменения состояния процессов.

3.Вызвать текстовый редактор и набрать подготовленные программы.

4.Откомпилировать программы и получить загрузочные модули.

5.С помощью команды chmod установить в файле, содержащем загрузочный модуль первой программы, признак, по которому процесс при выполнении функции exec сменит свои текущие эффективные идентификаторы на идентификаторы пользователя и группы владельца файла. Эта команда должна быть задана в следующем виде:

chmod a+s имя файла

6. Скопировать загрузочный модуль первой программы в каталог другого пользователя (это действие должен выполнить другой пользователь с помощью команды

ср).

7.Поочередно запустить обе программы и проанализировать результаты их работы.

8.Распечатать тексты программ и файлы, полученные в результате выполнения команды ps и программ.

3.4. Содержание отчета

Отчет по лабораторной Зработе должен содержать листинги программы и файлов результатов.

3.5. Защита работы

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

3.6. Контрольные вопросы

1.Сколько потомков и предков может иметь процесс?

2.В чем разница между реальным и эффективным идентификаторами пользователя?

3.Как можно изменить эффективный идентификатор?

4.При каком условии у процесса произойдет смена предка?

Лабораторная работа 4 СИНХРОНИЗАЦИЯ РАБОТЫ ПРЕДКОВ И ПОТОМКОВ

12 - -

Цель работы: знакомство с системными функциями, с помощью которых можно приостанавливать и синхронизировать работу процессов предка и потомока.

4.1. Общие сведения

После создания нового процесса родительский процесс может выполняться параллельно с потомком или ждать его завершения. Ожидать завершения потомков предок может с помощью функций wait(int * stat_loc) и waitpid (pid_t pid, int* stat_loc, int options). Системная функция wait приостанавливает обратившийся к ней процесс до тех пор, пока не завершится или не будет остановлен один из его потомков, или процесс не получит сигнал, который им не игнорируется. При окончании работы или остановке одного из потомков wait возвратит его идентификатор, а stat_loc будет указывать на переменную, в которой будут содержаться код завершения потомка и информация о сигнале, вызвавшем завершение или остановку потомка. Если выход из функции wait произошел вследствие получения процессом незамаскированного сигнала или отсутствия потомков, то возвращается -1. Для анализа значения, переданного по указателю stat_loc, можно воспользоваться макросами, определенными в библиотечном файле sys/wait.h:

WIFEXITED( *stat_loc) - возвращается ненулевое значение, если потомок завершился нормально;

WEXITSTATUS( *stat_loc) - если потомок завершился нормально, то передаются младшие 8 бит аргумента функции exit или значение, возвращаемое потомком при выходе из функции main.

Функция waitpid позволяет предку ожидать завершения конкретного потомка или группы потомков. Множество потомков, завершение которых ожидает процесс предок, определяется параметром pid.

Параметр stat_loc интерпретируется так же, как в функции wait, а параметр options может быть либо 0, либо задаваться посредством двух флагов WNOHANG и WUNTRACED, которые могут объединяться операцией логического сложения. Флаг WNOHANG указывает, что не требуется переводить процесс в состояние ожидания, если в данный момент требуемый потомок не остановлен или не закончил работу. В этом случае функция waitpid возвратит значение 0. По флагу WUNTRACED функция waitpid возвратит код завершения остановленного потомка только один раз, при остальных обращениях будет передан 0.

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

или влечет завершение процесса. Функция sleep возвращает 0, если она завершается

13 - -