Отчет по лабораторной работе.



Отчет по лабораторной работе должен содержать:

· текст программ модели;

· текстовое или графическое описание алгоритмов функционирования компонентов модели;

· протокол с результатами работы модели.

 

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

Тема: Обмен информацией между процессами. Средства IPC (межпроцессного взаимодействия). Каналы и очереди.

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

Теоретические сведения.

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

Каналы - общие сведения

Программный канал в Unix/Linux представляет собой одно из средств взаимодействия между процессами. Само название (pipe, дословно - трубка) достаточно точно передаст смысл функционирования этого средства. Канал подобен трубопроводу, проложенному между двумя процессами, и по этому трубопроводу процессы могут пересылать друг другу данные. Подобно трубопроводу, канал имеет собственную емкость, данные, направленные в канал процессом-отправителем, не обязательно должны быть немедленно прочитаны процессом-получателем, но могут накапливаться в канале. Как и у трубопровода, емкость канала конечна, когда она будет исчерпана, запись в канал становится невозможной.

Операционные системы Unix/Linux предоставляют в распоряжение программистам два вида каналов - именованные и неименованные. Работа с обоими видами во многом подобна работе с файлами.

Неименованные каналы

Неименованный канал является средством межпроцессного взаимодействия между двумя процессами - родительскими дочерним. Родительский процесс создает канал при помощи системного вызова: pipe () - создание неименованного программного канала

Синтаксис

int pipe(int fd[2]);

 

Описание

pipe создает неименованный программный канал и возвращает два файловых дескриптора: f d [ 0 ] - для чтения из канала и f d [ 1 ] - для заниси в канал.

Дальнейшая работа с каналом происходит так же, как с открытым файлом.

Возвращаемое значение

При нормальном выполнении возвращает 0. При ошибках выполнения возвращает -1 и устанавливает errno.

Массив из двух целых чисел является выходным параметром этого системного вызова. Если вызов выполнился нормально, то этот массив содержит два файловых дескриптора, fd [ 0 ] является дескриптором для чтения из канала, fd [ 1 ] - дескриптором для записи в канап. Когда процесс порождает другой процесс, дескрипторы родительского процесса наследуются дочерним процессом, и, таким образом, прокладывается трубопровод между двумя процессами. Естественно, что один из процессов использует канал только для чтения, а другой - только для записи (сами представьте себе, что произойдет, если это правило будет нарушаться). Поэтому, если, например, через канал должны передаваться данные из родительского процесса в дочерний, родительский процесс сразу после запуска дочернего процесса закрывает дескриптор канала для чтения, а дочерний процесс закрывает дескриптор для записи. Если нужен двунаправленный обмен данными между процессами, то родительский процесс создает два канала, один из которых используется для передачи данных в одну сторону, а другой - в другую. После получения процессами дескрипторов канала для работы с каналом используются файловые системные вызовы:

int read (int pipe_ fd, void *area, int cnt);

int write (int pipe fd, void *area, int cnt);

Read ()

чтение из файла

Синтаксис

int read (int fd, void *buf, int nbyte);

Описание

read читает nbyte байтов из файла (устройства, канала), определяемого файловым дескриптором fd в область памяти, адрес которой задается указателем buf.

На некоторые случаи выполнения read влияет флаг O_NDELAY, установленный в системном вызове open ():

· При попытке чтения из заблокированного файла:

o если флаг O_NDELAY установлен, вызов read завершается и возвращает -1;

o если флаг 0_NDELAY не установлен, вызов read приостанавливает процесс до разблокирования файла.

· При попытке чтения из пустого канала:

o если флаг 0_NDELAY установлен, вызов read завершается и возвращает 0;

o если флаг 0_NDELAY не установлен, вызов read приостанавливает процесс до появления данных в канале.

Возвращаемое значение

При нормальном выполнении read возвращает число прочитанных байтов. Это число может быть меньше, чем значение параметра nbyte, если конец файла встретится раньше, чем будет прочитано nbyte байтов. Возвращаемое значение 0 обычно означает попытку чтения после конца файла.

При ошибках выполнения read возвращает -1 и устанавливает errno.

Write ()

запись в файл

Синтаксис

int write (int fd, void *buf, int nbyte);

Описание

write записывает nbyte байтов в файл (устройство, канала), определяемый файловым дескриптором fd, из области памяти, адрес которой задается указателем buf.

При попытке записи в заблокированный файл:

· если флаг 0_NDELAY установлен, вызов write завершается и возвращает -1;

· если флаг 0_NDELAY не установлен, вызов write приостанавливает процесс до разблокирования файла.

При попытке записи в переполненный канал:

· если флаг 0_NDELAY установлен, вызов завершается и возвращает 0;

· если флаг 0_NDELAY не установлен, вызов write приостанавливает процесс до появления данных в канале.

Возвращаемое значение

При нормальном выполнении write возвращает число реально записанных байтов.

При ошибках выполнения write возвращает -1 и устанавливает errno.

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

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

При завершении использования канала процесс выполняет системный вызов:

int close(int pipe_fd);

 

Close ()

закрытие файла

Синтаксис

int close (int fd);

Описание

close закрывает файл (устройство, канал), определяемый файловым дескриптором fd, полученным ранее по системному вызову open, create или pipe

При успешном выполнении close возвращает 0. При ошибках выполнения возвращает -1 и устанавливает errno.

Если родительский процесс, создавший канал, порождает несколько дочерних процессов, то все дочерние процессы подключены к другому концу канала. Если, например, родительский процесс выводит данные в канал, то они "достанутся" тому дочернему процессу, который раньше выполнит системный вызов read () .


Дата добавления: 2018-08-06; просмотров: 371; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!