Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
IT4.doc
Скачиваний:
8
Добавлен:
03.03.2016
Размер:
97.79 Кб
Скачать

3.3 Программные каналы

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

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

Каналы обращаются с данными в порядке «первый вошел – первым вышел» (first-in first-out, или сокращенно FIFO). Другими словами, данные, которые помещаются в канал первыми, первыми и считываются на другом конце канала. Этот порядок нельзя изменить, поскольку вызов lseek не работает с каналами.

Таким образом, можно представлять себе канал как безымянный файл с необычным поведением. Работа с таким файлом напоминает проталкивание шаров через трубу - с одного конца мы вталкиваем данные, с другого конца - вынимаем их.

Канал создается системным вызовом pipe:

#include <unistd.h>

int pipe(int array[2]);

Системный вызов pipe() создает программный канал и присоединяет к двум концам канала два файловых дескриптора. Файловый дескриптор array[0] используется на том конце канала, откуда производится чтение, а файловый дескриптор array[1] присоединяется к концу канала, куда производится запись данных. Внутреннее устройство канала, как и внутреннее устройство открытого файла, скрывается ядром. Процесс видит только два файловых дескриптора.

Для создания двух процессов, которые взаимодействуют между собой через программный канал, нужно совместно использовать вызовы pipe() и fork(). При вызове fork() каждому из двух процессов достанется в наследство пара дескрипторов array[0] и arrray[1], обеспечивающих соединение с программным каналом. Оба процесса имеют возможность записывать и читать данные из канала. Однако программный канал будет использоваться более эффективно, если один процесс записывает данные в канал, а другой процесс читает данные из канала. Для этого, каждый процесс должен выполнять либо чтение из канала, либо запись в него и закрывать дескриптор файла, как только он стал не нужен. Для этого, процесс, выполняющий запись в канал, должен закрывать дескриптор читаемого конца канала array[0], а процесс, осуществляющий чтение, должен закрывать дескриптор записываемого конца канала array[1].

4 Пример программы

Слово состояния устройства в системе ввода-вывода представляется в виде:

№ разряда

15

14

13

12

11

10

09

08

07

06

05

04

03

02

01

00

Значение

C

C

C

C

C

0

F

B

N

N

N

N

N

N

N

N

где: C..C - код состояния

F - признак ошибки (1/0)

B - признак занятости (0/1)

N..N - количество байт, переданных в последней операции.

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

При вызове программы в командной строке нужно указать количество генерируемых наборов чисел.

Текст программы приведен в приложении.

Пример работы программы:

$ ./lr41 2

Родительский процесс pid=4762

Порожденный процесс pid=4763

набор отправлен в канал

набор принят из канала

Код состояния = 2

Признак ошибки = 1

Признак занятости = 0

Количество переданных байт = 253

набор отправлен в канал

набор принят из канала

Код состояния = 25

Признак ошибки = 0

Признак занятости = 0

Количество переданных байт = 176

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