Операционные системы -вопросы теории

Код создающий конвейер



Пример 7.7. Код, создающий конвейер при помощи труб

#include <unistd.h>

void pipeline(void) {
/* stage 1 */
int pipel[2];
int childl;
int pipe2[2];
int child2;
int child3;

pipe(pipel);

if ((childl=fork())==0) {
close(pipel[0]); /* Закрыть лишний конец трубы */


closed); /* Переназначить стандартный вывод */
dup(pipel[1]);
close(pipel[1]);
/* Исполнить программу */
execlpC'du", "du", "-s", ".", NULL);
/* Мы можем попасть сюда только при ошибке exec */
perror("Cannot exec");
exit(0);
}
close(pipel [1] ) ;
if (childl==-l) {
perror("Cannot fork");
}
/* stage 2 */
pipe(pipe2);
if ( (child2=fork() )==0) { '. close (0) ; /J" Переназначить стандартный ввод */
dup(pipel[0]} ; close (pipel [0] ) ;
•'close (pipe2 [0] ) ; /* Закрыть лишний конец трубы */ close (1) ; /* Переназначить стандартный вывод */
close (pipe2 [1] ) ;
/* Исполнить программу */
execlp ("sort", "sort", "-nr", NULL);
/* Мы можем попасть сюда только при ошибке exec */
perror ("Cannot exec");
exit(O) ;
}
close (pipel [0] ) ;
close (pipe2 [1] ) ;
if (child2==-l) {
perror ("Cannot fork");
}
/* stage 3 */
if ( (child3=fork() )==0) {
close (0) ; /* Переназначить стандартный ввод */
dup(pipe2 [0] ) ;
close (pipe2 [0] ) ;
/* Исполнить программу */
execlp ("tail", "tail", "-1", NULL) ;
/* Мы можем попасть сюда только при ошибке exec */
perror ("Cannot exec");
exit (0) ;
}
close (pipe2 [0] ) ;
if (child3==-l) {
perror ("Cannot fork");
}
while (wait (NULL) !=-!) ;
return ;
}

Понятно, что такие трубы можно использовать только для связи родственны задач, т. е. таких, которые связаны отношением родитель-потомок или являются потомками одного процесса.
Для связи между неродственными задачами используется другое средство. именованные трубы (named pipes) в System V и UNIX domain sockets в BSD UNIX. В разных системах именованные трубы создаются различными систем ными вызовами, но очень похожи по свойствам, поэтому стандарт POSIX пред лагает для создания именованных труб библиотечную функцию mkfifc {c--ls. char * name, mode_t flags);. Эта функция создает специальный файл" Открывая такой файл, программа получает доступ к одному из концов трубы Когда две программы откроют именованную трубу, они смогут использовать ее для обмена данными точно так же, как и обычную.
Современные системы семейства Unix предоставляют возможность для одновременной работы с несколькими трубами (а также с другими объектами, описываемыми дескриптором файла — собственно файлами, сокетами и т. д.)_, системный вызов select. Этот вызов возвращает список дескрипторов файлов, которые способны передать или принять данные. Если ни один из дескрипторов не готов к обмену данными, select блокируется.
Трубы широко используются системами семейства Unix, и они внесены в стандарт POSIX. Ряд операционных систем, не входящих в семейство Unix, например VxWorks, также предоставляют этот сервис.



Содержание раздела