Московский Государственный Институт Электроники и Математики (Технический Университет)

Курсовая работа по дисциплине

«Операционные системы»

Вариант №6

Выполнили:

СК-41, АВТ

Проверил:

Преподаватель каф. МОСОиУ

Москва 2007

Лабораторная работа №1

Задание:

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

Описание:

I. Основная функция main()

1.  Объявляем функцию обработки прерывании sig().

2.  Объявляем дескрипторы межпроцессного канала g[2].

Это массив из двух элементов, первый элемент которого g[0] - дескрипторы межпроцессного канала на чтение из канала, второй - g[1] - дескрипторы межпроцессного канала на запись в канал.

3.  Объявляем массив из 400 элементов buf[400], в который в дальнейшем будем считывать информацию из межпроцессного канала.

4.  Системный вызов signal(SIGINT, sig) означает, что в случае прихода сигнала прерываний SIGINT , управление передается функции sig()

5.  pipe(g) – Создание межпроцессного канала - коммуникационный канал между двумя взаимосвязанными процессами.

6.  Для распараллеливания процессов используем системный вызов fork().

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

НЕ нашли? Не то? Что вы ищете?

fork()==0 – процесс –сын.

fork()==1 – процесс – отец.

7.  Процесс - сын:

7.1.  При создании программы автоматически создаются три файла – пользовательские дескрипторы файлов:

0  /dev/tty - файл на стандартный ввод.

1 /dev/tty - файл на стандартный вывод.

2 /dev/tty - файл на стандартное выполнение.

Строка: close(1) означает закрытие стандартного вывода.

7.2.  close(g[0]) - закрытие межпроцессного канала на чтение.

7.3.  Системный вызов dup2 позволяет осуществить доступ к одному и тому же файлу из одного и того же пользовательского процесса через два различных пользовательских дескриптора файла.

dup2(g[1],1) - дублирование дескриптора межпроцессного канала на стандартный вывод.

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

7.4.  close(g[1]) – удаляем копию.

7.5.  Системный вызов execl осуществляет вызов новой команды вместо уже выполняющейся без возврата в вызывающую программу.

execl("/usr/bin/users","users",0) - вывод всех пользователей, работающих в данный момент в системе.

8.  Процесс – отец:

8.1  close(g[1]) - закрытие межпроцессного канала на запись.

8.2  dup2(g[0],0) - дублирование дескриптора межпроцессного канала на стандартный ввод.

8.3  Следующим действием, в бесконечном цикле, считываем построчно из межпроцессного канала информацию в массив buf и выводим на экран его значение.

II. Функция обработки прерываний sig().

1.  При каждом заходе в функцию увеличиваем счетчик прерываний на 1.

2.  Если число прерываний достигло трех, выводим на экран сообщение:

Последние прерывание

время его поступления и выходим из программы

3. Если число прерываний меньше трех, выводим на экран сообщение:

Прерывание № n

И время его поступления - printf(__TIME__ "\n")

Код:

/* Включаем заголовочные файлы*/

#include <stdio. h>

#include <signal. h>

int i=0; /* Счетчик прерываний */

void sig() /* Функция обработки прерываний */

{

i++;

if(i==3)

{

printf("Последние прерывание\n");

printf(__TIME__ "\n");

exit(0);

}

else

{

printf("Прерывание № %d\n",i);

printf(__TIME__ "\n");

sleep(2);

}

}

main()

{

void sig(); /* Объявляем функцию обработки прерывании*/

int g[2]; /*Объявляем дескрипторы межпроцессного канала */

char buf[400]; /*Объявляем массив из 400 элементов*/

signal(SIGINT, sig); /* В случае прихода сигнала прерываний SIGINT

управление передается функции sig */

pipe(g); /* Создание межпроцессного канала*/

if (fork()==0) /* Распараллеливание процесса */

{ /* Процесс сын */

close(1); /* Закрытие стандартного вывода */

close(g[0]); /* Закрытие межпроцессного канала на чтение */

dup2(g[1],1); /* дублирование дескриптора межпроцессного канала на

стандартный вывод */

close(g[1]); /* Удаляем копию*/

execl("/usr/bin/users","users",0); /* Вывод всех пользователей, работающих в

данный момент в системе */

}

else

{ /* Процесс отец */

close(g[1]); /* Закрытие межпроцессного канала на запись */

dup2(g[0],0); /* дублирование дескриптора межпроцессного канала на

стандартный ввод */

while(1)

{

if(scanf("%s",buf)==EOF) /* Считывание построчно из межпроцессного

канала информацию в массив buf */

break;

printf("%s\n",buf); /* Вывод на экран значение переменной buf*/

}

sleep(2);

}

}

Лабораторная работа №2

Задание:

Выполнить лабораторную работу №1 на интерпретаторе команд shell.

Описание:

1.  Объявляем переменную numsig=0; - счетчик прерываний.

2.  Функция обработки прерываний signal()

numsig=`expr $numsig + 1`; - увеличиваем значение счетчика на 1.

expr –команда, осуществляющая вычисление арифметических выражений, выполняет следующие действия: + , - , * , / , % (остаток от деления).

expr $numsig + 1 –означает, что берем значение переменной numsig ($) и увеличиваем на 1.

`…` - присвоить результат выполнения команды.

Т. е. получается: присвоить переменной numsig результат выполнения команды: увеличить значение переменной numsig на 1.

Команда test осуществляет проверку файлов, числовых величин и цепочек символов.

Выражение: if test $numsig - eq 3 then

Означает: если значение переменной numsig равно трем (-eq 3), то ….

- eq ( = ) - le ( <= ) - qt ( > )

- lt (< ) - ge ( >= ) - ne ( != )

3.  Основная функция

Команда trap означает, что при получении сигнала запускается программа обработчик сигналов.

trap signal SIGINT - в случае прихода сигнала прерывании (2 –SIGINT) управление передается функции signal().

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

who | awk '{print$1}'

Команда who выдает список всех пользователей, работающих в настоящее время в системе. Результат выполнения этой команды поступает на вход команды awk '{print$1}'.

Команда awk '{print$1}' – выводит на экран только первый столбец из полученной информации.

Код:

numsig=0; #счетчик прерывании

signal() #Функция обработки прерывании

{

numsig=`expr $numsig + 1`;

echo "Последнее Прерывание";

date | awk '{print$4}';

sleep 2;

}

trap signal 2 #В случае прихода сигнала прерывании, управление передается в signal()

sleep 1;

who | awk '{print$1}'

sleep 1;

sleep 1;

sleep 1;