Системное программное обеспечение - Учебное пособие (Терехин А.Н.)

4.6       реализация конвейера.

Пример реализации конвейера print|wc – вывод программы print будет подаваться на вход программы wc. Программа print печатает некоторый текст. Программа wc считает количество прочитанных строк, слов и символов.

#include <sys/types.h>

#include <unistd.h>

#include <stdio.h>

int main(int argc, char **argv)

{

int fd[2];

pipe(fd);  /*организован канал*/     

if (fork())

{

/*процесс-родитель*/

dup2(fd[1], 1); /* отождествили стандартный вывод с файловым дескриптором канала, предназначенным для записи */

close(fd[1]);   /* закрыли файловый дескриптор канала, предназначенный для записи */

close(fd[0]);   /* закрыли файловый дескриптор канала, предназначенный для чтения */

exelp(“print”, ”print”, 0); /* запустили программу print */

}

/*процесс-потомок*/

dup2(fd[0], 0); /* отождествили стандартный ввод с файловым дескриптором канала,   предназначенным для чтения*/

close(fd[0]);   /* закрыли файловый дескриптор канала, предназначенный для чтения */

close(fd[1]);  /* закрыли файловый дескриптор канала, предназначенный для записи */

execl(“/usr/bin/wc”, ”wc”, 0); /* запустили программу wc */

}

 

 Совместное использование сигналов и каналов – «пинг-понг».

Пример программы с использованием каналов и сигналов для осуществления связи между процессами –  весьма типичной ситуации в системе. При этом на канал возлагается роль среды двусторонней передачи информации, а на сигналы – роль системы синхронизации при передаче информации. Процессы посылают друг другу целое число, всякий раз увеличивая его на 1. Когда число достигнет некоего максимума, оба процесса завершаются.

#include <signal.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

 

#define MAX_CNT 100

int target_pid, cnt;

int fd[2];

int status;

 

void SigHndlr(int s)  

{       

/* в обработчике сигнала происходит и чтение, и запись */

          signal(SIGUSR1, SigHndlr);

                  

          if (cnt < MAX_CNT)

          {

                   read(fd[0], &cnt, sizeof(int));

                   printf("\%d ", cnt);

                   cnt++;

                   write(fd[1], &cnt, sizeof(int));

/* посылаем сигнал второму: пора читать из канала */

                   kill(target_pid, SIGUSR1);

          }

          else

                   if (target_pid == getppid())

                   {

/* условие окончания игры проверяется потомком */

printf("Child is going to be terminated ");

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

                             /* завершается потомок */

                             exit(0);

                   } else

kill(target_pid, SIGUSR1);

}

 

int main(int argc, char **argv)

{

          pipe(fd); /* организован канал */     

          signal (SIGUSR1, SigHndlr);

/* установлен обработчик сигнала для обоих процессов */

          cnt = 0;

 

          if (target_pid = fork())

          {

/* Предку остается только ждать завершения потомка */

                   wait(&status);

printf("Parent is going to be terminated ");

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

                   return 0; 

          }

          else

          {

                   /* процесс-потомок узнает PID родителя */

                   target_pid = getppid();

          /* потомок начинает пинг-понг */

                   write(fd[1], &cnt, sizeof(int));

                   kill(target_pid, SIGUSR1);

                   for(;;); /* бесконечный цикл */

          }

}