Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
мои шпоры ОСиСП(1).doc
Скачиваний:
30
Добавлен:
26.09.2019
Размер:
1.63 Mб
Скачать

Билет 16

1.Каналы в ос unix (16) – 80

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

#include <unistd.h>

Int pipe(int fd[2]);

Fd[0] – используется для чтения

Fd[1] – используется для записи

В результате выполнения системного вызова массив fd будет содержать два дескриптора файлов. А в случае ошибки переменная errno будет установлена:

EMFILE – превышено максимальное число дескрипторов для пользователя.

ENFILE – переполнение таблицы открытых файлов.

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

В большинстве UNIX-систем каналы однонаправленные, т.е. для чтения данных из канала используется fifo[0], а для записи - fifo[1]

Можно определить две типовые схемы взаимодействия.

1. Родитель - сын: родитель вызывает pipe для создания канала, а затем с помощью fork порождает сына. Т.к. порожденный процесс имеет копию дескрипторов файлов процесса-отца, то теперь процесс-отец и процесс-сын могут взаимодействовать через fifo[0] и fifo[1]

2. Брат - брат: родитель вызывает pipe, а затем порождает 2 или более сыновей-братьев. Процессы-браться взаимодействуют между собой через fifo[0] и fifo[1]

Д ля реализации двунаправленной связи используют два канала.

Применение неименованных каналов реально только для взаимодействия родственных процессов. То есть неименованный канал должен быть создан до создания процессов. И неименованные каналы закрываются при завершении процесса.

Чтобы устранить эти недостатки предлагается механизм именованных каналов (или канал FIFO). При его создании создается и его имя:

#include<sys/types.h>

#include<sys/stat.h>

Int mkfifo(const char *pathname,mode_t mode);

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

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

Размер канала и взоимодействие процессов при передаче данных

Буфер, связанный с каналом, имеет конечный размер. Минимальный размер канала – 512 байт. При попытке записать данные в уже заполненный канал, ядро заблокирует процесс до тех пор, пока другой процесс не считает из канала достаточное количество данных, чтобы заблокированный процесс смог возобновить запись. Таким образом ядро системы пытается организовать в канал запись данных неделимой порцией. Действия функции чтения более простые. При её выполнении проверяется является ли канал пустым, если пуст, то функция чтения блокируется до тех пор, пока другой процесс не запишет данные в канал. А если же функция чтения запрашивает больше данных, чем есть в канале, то завершает выполнение после прочтения имеющихся в канале данных, даже если их меньше, чем функция запрашивает.

Интересные моменты: если больше нет процессов, которые могли бы выполнить запись в канал и канал при этом пуст, то любой процесс, который попытается выполнить чтение из канала получит пустой блок, а процессы, которые ожидали чтения из канала продолжат свою работу, а их вызовы чтения вернут 0-ое значение; если больше нет процессов, которые могли бы выполнить чтение из канала, то ядро опирационной системы посылает сигнал SIGPIPE всем процессам ожидающим запись. По умолчанию этот сигнал приведет к остановке процесса. А если его перехватят, то после завершения процесса обработки, функция записи вернет значение -1, а переменная errno получит код EPIPE.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]