Межпроцессное взаимодействие в ОС Linux

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

 

I. Каналы (unnamed pipes)

 

Неименованный канал, или просто канал, - это однонаправленный канал связи в ОС UNIX. Каждый канал имеет два конца: входной (для записи, upstream end) и выходной (для чтения, downstream end). Каждый из двух концов канала имеет свой собственный дескриптор, являющийся целым числом, как и дескриптор файла. Оба дескриптора создаются при создании канала системным вызовом pipe(). Используя канал, один процесс может записывать данные во входной конец канала, а другой процесс может читать эти данные из выходного конца канала.

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

В команде оболочки канал создается при помощи символа "|" (см. лабораторную работу 1).

В программе неименованный канал создается при помощи системного вызова pipe():

ret = pipe (fd);

где ret - код возврата целого типа, fd - массив int fd[2]из двух элементов, в который записываются значения в результате этого системного вызова. Системный вызов pipe() возвращает 0 в случае успеха и -1 в случае ошибки.

Если системный вызов pipe() завершился успешно, то в первый элемент массива, fd[0], записывается дескриптор выходного конца созданного канала (для чтения), и в fd[1] - дескриптор входного конца (для записи).

В этой части лабораторной работы необходимо создать неименованный канал в начале работы родительского процесса, затем создать два дочерних процесса. Один из этих дочерних процессов будет выполнять какую-либо команду оболочки (например, ls -l /home/student) и записывать результаты работы во входной конец канала. Другой дочерний процесс (выполняющий, например, команду sort) будет получать данные из выходного конца того же канала. Таким образом, результат выполнения этих двух дочерних процессов будет идентичен выполнению последовательности двух команд оболочки (см. рис.1):