- •Раздел 1. Операционная система unix. Введение в операционную систему unix
- •Отличительные черты ос unix
- •Основы архитектуры операционной системы unix Модель системы unix.
- •Структура ядра ос unix.
- •Основы файловой системы ос unix
- •Типы файлов
- •Структура файловой системы unix
- •Владельцы файлов
- •Права доступа к файлу
- •Дополнительные атрибуты файлов
- •Устройства
- •Маска создания файла
- •Программы Oc unix
- •Процессы ос unix
- •Типы процессов
- •Атрибуты процесса
- •Процесс создания и запуска программ
- •Системный вызов завершения процесса exit
- •Системные функции типа exec
- •Обработка ошибок
- •Ограничения для процессов
- •Пользователи системы, Атрибуты пользователя
- •Средства ВзаимодействиЯ между процессАми
- •Сигналы
- •Посылка сигналов.
- •Int raise (int sig); // посылает сигнал вызывающему процессу (т.Е. Самому себе).
- •Обработка сигналов.
- •Набор сигналов.
- •Файловая подсистема ос unix
- •Индексный дескриптор
- •Блоки хранения данных
- •Недостатки и ограничения файловой системы s5fs
- •Файловая система ffs (Fast File System)
- •Основные отличия ffs от s5fs
- •Ограничения ffs
- •Каталоги ffs
- •Раздел 2. Взаимодействие процессов. Процесс, Понятие и классификация
- •Ресурсы, Понятие и классификация
- •Взаимодействие процессов Задача взаимного исключения
- •Integer очередь;
- •ОБобщенная задача взаимного исключения
- •Integer очередь;
- •Синхронизирующие примитивы (семафоры)
- •Процесс 1 :
- •Процесс 2 :
- •V(свободно);
- •Задача “производитель-потребитель” применение ОбщиХ семафорОв
- •Задача “производитель-потребитель” (буфер ограниченНый)
- •Взаимодействие через переменные состояния
- •Integer array желание[1:n], сп[1:n];
- •Integer чпб, бб, рб, чсеб, I;
- •Integer разм_п, n, max, nmax;
- •Проблема тупиков
- •Алгоритм банкира
- •Integer Св_Деньги; boolean Безопасно;
- •If ((Завершение_под_сомнением [I]) and
- •Применение алгоритма банкира
- •V(Взаимн_искл);
- •V(Возвращенные_Талеры[Номер_Клиента[m]]);
- •If (Попытка_выдать_талер_клиенту(h))
- •Монитороподобные средства синхронизации
- •Механизм типа «критическая область»
- •Механизм типа «условная критическая область»
- •Var s : semaphore; считывание : boolean; m : t;
- •Раздел 3. Вычислительные структуры. Машины, управляемые контроллерами (устройствами управления)
- •Усовершенствованная структура вычислительной машины, управляемой контроллерОм
- •Системы с операционным конвейером
- •Мультипроцессорные системы
- •Транспьютеры
- •Распределение памяти в транспьютерах
- •Диспетчеризация процессов
- •Организация ВводА / выводА в транспьютере.
- •Гарвардская архитектура на примере процессоров семейства adsp
Средства ВзаимодействиЯ между процессАми
Неименованные каналы.
#include <unistd.h>
int pipe(int fifo[2]);
Системный вызов pipe(), который создаёт коммуникационный канал, между двумя взаимосвязанными процессами, например: между отцом и сыном или двумя процессами, порождёнными одним родительским процессом. Эта функция создаёт файл канала, который является временным буфером и использующийся для того, чтобы вызывающий процесс мог записывать туда данные для других процессов и считывать данные для себя от других процессов. Файлу канала имя не присваивается, поэтому он и называется “неименованный ”. Канал освобождается сразу после того, как все процессы закроют файловые дескрипторы, ссылающиеся на этот канал.
Аргумент системного вызова pipe() массив из двух целых чисел. Для чтения данных из канала используется элемент fifo[0], а для записи fifo[1]. При успешном завершении pipe() возвращает 0, а при ошибке -1.
К данным, хранящимся в канале, доступ производится последовательно по принципу First In First Out. Процесс не может использовать функции позиционирования в канале. Данные удаляются из канала сразу после считывания.
Можно определить две типовые схемы взаимодействия через канал:
Отец <-> сын: родительский процесс использует pipe() для создания канала, а затем с помощью fork () порождает процесс-сын. Порожденный процесс имеет копию дескрипторов файлов процесса-отца, и процесс-отец и процесс-сын могут взаимодействовать через fifo[0] и fifo[1]
Брат <-> брат: отец сначала производит системный вызов pipe(), а затем порождаются 2 или более сыновей-братьев. Процессы-братья взаимодействуют между собой через fifo[0] и fifo[1]
Программа взаимодействия отца с сыном.
#include <iosream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{
pid_t child_pid, pid;
int status, fifo[2];
char buf[80];
if (pipe(fifo)==-1) perror (“pipe”); _exit(1);
switch(child_pid=fork())
{
case -1 : perror (“fork”); _exit(2);
case 0 : close(fifo[0]); //сын
write(fifo[1], “сын %d завершил работу \n”, getpid());
close(fifo[1]);
_exit(0);
}
close(fifo[1]); // отец
while (read(fifo[0],buf,80)) printf(“\n %s\n”,buf);
close(fifo[0]);
if ((waitpid(child_pid, &status, 0)==child_pid) && WIFEXITED(status))
return(WEXITSTATUS(status));
return(3);
}
Т. к. буфер, связанный с каналом, имеет конечный размер, то при попытке процесса записать данные в уже заполненный канал, ядро заблокирует процесс до тех пор, пока другой процесс не произведёт считывание из канала достаточного количества данных, а если канал пуст, а процесс пытается прочитать из него данные, то он будет блокироваться до тех пор, пока другой процесс не запишет данные в канал. Такой механизм блокировки можно использовать для синхронизации и выполнения 2-ух и более процессов.
Количество процессов, которые могут параллельно подсоединяться к любому дескриптору канала, не ограничено, но отсутствует возможность монопольного захвата канала. Имеются предпосылки разрыва последовательности данных, передаваемых через канал одним из процессов. То же самое относится и к чтению.
Для предотвращения таких недостатков коммуникационный канал обычно делают однонаправленным и устанавливают его только для связи между двумя процессами, чтобы один процесс является отправителем, а другой получателем. Если оба процесса нуждаются в двунаправленном коммуникационном канале, то целесообразно для связи между ними создать два канала. Один работает на передачу данных от одного процесса к другому, а второй – наоборот.
Двунаправленный канал
Два однонаправленных канала
Если дескриптора файла, связанного с записывающей стороной канала не существует, то эта сторона считается закрытой и любой процесс, пытающийся считать данные из канала, получает оставшиеся в нем данные. Если все данные прочитаны, а процесс продолжает чтение, он получает признак конца файла. Если же не существует дескриптора файла, связанного с читающей стороной канала, а процесс пытается записать данные в канал, то ядро формирует для данного канала сигнал SIGPIPE. Действие по умолчанию на этот сигнал завершение процесса.
Есть системные вызовы, контролирующие работу с каналами.