Задача №1 - конвейер из двух фильтров

Управление процессами в ОС UNIX

 

Цель работы

Ознакомиться со средствами организации взаимодействия процессов в ОС UNIX.

 

Содержание работы

  1. Ознакомиться со средствами организации взаимодействия процессов в ОС UNIX.
  2. Для указанного варианта составить следующие программы на языке Си:
    • реализующую конвейер из двух фильтров (формулировка одного фильтра задана, второй фильтр необходимо придумать);
    • организующую взаимодействие двух процессов через неименованныйпрограммный канал;

· организующую взаимодействие двух процессов через именованныйпрограммный канал.

Примечание. Проиллюстрировать работу неименованногопрограммного канала и именованногопрограммного канала на макетных программах с применением фильтров, используемых в задаче №1.

3. Защитить лабораторную работу, ответив на контрольные вопросы.

Методические указания к лабораторной работе

 

Таблица 1. Основные системные вызовы, используемые в задачах

  fork() Системный вызов, создающий новый процесс (потомок), который является практически полной копией процесса-родителя, выполняющего этот вызов
  wait(int *status) Ожидание завершения процесса-потомка родительским процессом
  execl() Все формы системного вызова exec превращают вызвавший процесс в новый процесс, который строится из обычного выполняемого файла, называемого в дальнейшем новым выполняемым файлом. Если системный вызов exec закончился успешно, то он не может вернуть управление, так как вызвавший процесс уже заменен новым процессом.
  pipe(p) p – целый массив из двух элементов: int p[2]; Дескриптор файла p[0] используется для представления конца канала, предназначенного для чтения, а дескриптор файла p[1] – для представления конца канала, предназначенного для записи.
  fdopen(<дескриптор_файла> <режим_открытия_файла>) fdopen ассоциирует поток с файловым дескриптором полученным от функции open()
  dup(p[0]) Наименьший доступный дескриптор файла, т.е. 0, и p[0], т.е. конец канала p для чтения, становятся синонимами
  close(0) Дескриптор файла 0 закрывается в связи с закрытием ассоциированного с ним файла, т.е. файла стандартного ввода

 

 

Задача №1 - конвейер из двух фильтров

 

Пример: Программная реализация конвейера ls | wc, подсчитывающего количество программ в текущем каталоге.

void main(void) /* LSWS.C */

/* Создание программного канала */

/* для команд ls и wc */

{

int pid, pid2;

int fd[2];

int status, dead;

switch(pid = fork())

{

case -1: /* Cбой при вызове fork() */

printf("Ошибка при вызове fork() #1 \n");

exit(1);

case 0: /* ПОТОМОК #1 */

pipe(fd);

 

switch(pid2 = fork())

{

case -1: /* Cбой при вызове fork() */

printf("Ошибка при вызове fork() #2 \n");

exit(2);

case 0: /* ПОТОМОК #2 */

close(0); dup(fd[0]); close(fd[0]); close(fd[1]);

execl("/usr/bin/wc", "wc", 0);

puts("Ошибка при вызове WC \n");

exit();

default: /* */

close(1); dup(fd[1]);

close(fd[1]); close(fd[0]);

execl("/bin/ls", "ls", 0);

puts("Ошибка при вызове LS\n");

exit();

default: /* ПРЕДОК ГЛАВНЫЙ */

dead = wait(&status);

exit();

}

}