Организация конвейера и перенаправления ввода-вывода.
Написать программу, моделирующую команду SHELL: (здесь pri - имена процессов, argi - аргументы процессов, f.dat - файл входных данных, f.res - файл результатов; в каждом из процессов pri использован стандартный ввод-вывод). Аргументы, необходимые этой программе, задаются в командной строке (массив argv[] ).
a) pr1½pr2½pr3
b) pr1½pr2 > f.res
c) pr1 < f.dat½pr2½pr3> f.res
d) pr1½pr2 >> f.res
e) pr1; pr2½pr3 > f.res
f) pr1½pr2½…½prn
g) pr1 < f.dat½pr2 arg2
h) pr1 arg1 < f.dat; pr2| pr3 >f.rez
Именованный канал FIFO
Как мы выяснили, доступ к информации о расположении pip'a в операционной системе и его состоянии может быть осуществлен только через таблицу открытых файлов процесса, создавшего pipe, и через унаследованные от него таблицы открытых файлов процессов-потомков. Поэтому изложенный выше механизм обмена информацией через pipe справедлив лишь для родственных процессов, имеющих общего прародителя, инициировавшего системный вызов pipe(), или для таких процессов и самого прародителя и не может использоваться для потокового общения с другими процессами. В операционной системе UNIX существует возможность использования pip'a для взаимодействия других процессов, но ее реализация достаточно сложна и лежит далеко за пределами наших занятий.
|
|
Для организации потокового взаимодействия любых процессов в операционной системе UNIX применяется средство связи, получившее название FIFO (от FirstInput First Output) или именованный pipe. FIFO во всем подобен pip'y, за одним исключением: данные о расположении FIFO в адресном пространстве ядра и его состоянии процессы могут получать не через родственные связи, а через файловую систему. Для этого при создании именованного pip'a на диске заводится файл специального типа, обращаясь к которому процессы могут получить интересующую их информацию. Для создания FIFO используется системный вызов mknod() или существующая в некоторых версиях UNIX функция mkfifo().
Следует отметить, что при их работе не происходит действительного выделения области адресного пространства операционной системы под именованный pipe, а только заводится файл-метка, существование которой позволяет осуществить реальную организацию FIFO в памяти при его открытии с помощью уже известного нам сиcтемного вызова open ().
После открытия именованный pipe ведет себя точно так же, как и неименованный. Для дальнейшей работы с ним применяются системные вызовы read(),write() и close(). Время существования FIFO в адресном пространстве ядра операционной системы, как и в случае с pip'oм, не может превышать время жизни последнего из использовавших его процессов. Когда все процессы, работающие с FIFO, закрывают все файловые дескрипторы, ассоциированные с ним, система освобождает ресурсы, выделенные под FIFO. Вся непрочитанная информация теряется. В то же время файл-метка остается на диске и может использоваться для новой реальной организации FIFO в дальнейшем.
|
|
Системный вызов mknod для создания FIFO
Прототип системного вызова:
#include <sys/stat.h>
#include <unistd.h>
int mknod(char *path, int mode, int dev);