Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы(ОС) / Lab3 / LabOS_3.doc
Скачиваний:
59
Добавлен:
17.04.2013
Размер:
62.98 Кб
Скачать

6

Лабораторная работа по курсу "Операционные системы" Процессы в ос Linux (I)

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

Идентификаторы процессов

Процессы в ОС Linux имеют уникальные номера - идентификаторы процессов (PID), являющиеся целыми числами, назначаемыми процессам при их создания. В программах, написанных на С/С++, предпочтительнее использовать для PID не тип int, а тип pid_t, описанный в файле <sys/types.h>.

Для получения программой PID собственного процесса используется системный вызов getpid, для получения PID родительского процесса - getppid.

Задание 1. Выполните программу pr1.c:

/* pr1.c */

#include <stdio.h>

#include <unistd.h>

int main()

{

printf("PID is %d\n", getpid());

printf("PPID is %d\n", getppid());

return 0;

}

Выполните программу несколько раз. Запишите значения PID и PPID и объясните результаты в отчете.

Просмотр активных процессов

Для просмотра активных процессов предназначены следующие команды:

  • ps (Process Status). Введенная без опций, команда ps показывает только те процессы, которые были запущены из данного терминального окна.

  • top показывает активные процессы в динамике.

  • pstree показывает активные процессы в виде дерева.

Задание 2.

2.1. Введите команду $ps.

Занесите в отчет полученную информацию. Введите команду ps со следующими опциями:

$ps -e -o pid,ppid,start_time,command

$ps -f -A

$ps -l

$ps -la

Законспектируйте информацию об использованных Вами опциях команды ps. Определите, какой процесс является родителем процесса ps, и какой - родителем его родителя и т.д. Для последней команды расшифруйте значения колонок листинга.

2.2. Введите команду $top.

2.3. Введите команду $pstree.

Код завершения процесса

В нормальной ситуации процесс завершается либо системным вызовом exit либо возвратом из функции main. Код завершения - это двухбайтное целое число, возвращаемое процессом своему родителю. Это число - аргумент функции exit или значение, возвращаемое функцией main. Старший байт кода возврата равен коду возврата программы (так называемый пользовательский код возврата). В младший байт ОС записывает причину завершения процесса (системный код возврата; при нормальном завершении процесса он равен нулю).

Создание процессов

Способ 1. Использование system.

При помощи функции system из стандартной библиотеки языка С stdlib можно выполнить команду изнутри программы, как если бы эта команда выла введена в оболочке. Команда system возвращает код возврата команды оболочки. При неудачном запуске оболочки код возврата равен 127, если произошли другие ошибки, то код возврата равен -1.

Задание 3. Выполните программу pr3.c, в которой запускается команда "ls -l /":

/* pr3.c */

#include <stdio.h>

#include <stdlib.h>

int main()

{

int ret_val;

ret_val = system("ls -l /");

printf("Return code is %d\n", ret_val);

return ret_val;

}

Запишите в отчет код возврата функции system при успешном и неуспешном (задайте для ls несуществующий каталог) выполнении. Выведите код завершения программы pr3.c также и из оболочки, пользуясь соответствующей переменной оболочки (см. лабораторную работу 1).

Создание нового процесса при помощи system не следует использовать в программах, т.к. он может вести себя по-разному в разных версиях Linux.

Способ 2. Использование fork.

Основной способ создания процессов - системный вызов fork, который создает дочерний процесс, являющийся копией своего родительского процесса. При неудаче fork возвращает -1. При успешном выполнении fork возвращает 0 в созданный дочерний процесс и возвращает PID дочернего процесса в родительский процесс.

Задание 4.

4.1. Выполните следующую программу:

#include <stdio.h>

#include <unistd.h>

int main()

{

fork(); printf("A\n");

fork(); printf("B\n");

return 0;

}

Сколько процессов будет выполнено? Сколько сообщений будет напечатано? Нарисуйте дерево процессов. Почему приглашение оболочки $ появляется раньше, чем программа завершает работу?

4.2. Выполните программу pr4.c:

/* pr4.c */

#include <stdio.h>

#include <sys/types.h>

#include <unistd.h>

int main()

{

pid_t child_pid;

printf("The main program process ID is %d\n", getpid());

child_pid = fork();

if (child_pid !=0) {

printf ("This is the parent process, with ID %d\n", getpid());

printf ("the child's process ID is %d\n", child_pid);

}

else

printf ("This is the child process, with ID %d\n", getpid());

return 0;

}

а) Запишите в отчет выходные данные, выведенные программой.

б) Распечатайте в дочернем процессе PID его родителя и выполните программу. Модифицируйте программу: после fork задержите выполнение родительского процесса на 3 единицы времени (при помощи библиотечной функции sleep), а дочернего - на 10 единиц. Распечатайте в дочернем процессе PID его родителя дважды: до и после sleep. Объясните в отчете полученные результаты.

Соседние файлы в папке Lab3