double arrow

Задача №2 - неименованные программные каналы


Пример: взаимодействие родственных процессов в дуплексном режиме (используются два программных канала) и переназначение стандартного ввода-вывода.

Пусть входной файл содержит команды форматирования (они начинаются с ‘.’ в первом символе строки) и текст:

.R

aaaaaaa

.B

ccccccc

. . .

Для решения задачи используем 2 параллельных процесса:

· textcount – читает текстовый файл и при передаче строк процессу count удаляет из них команды форматирования;

· count – подсчитывает получаемые от процесса textcount символы и по достижении конца текста посылает общее число знаков первому процессу.

Порождающий и порожденный процессы должны взаимодействовать, используя два канала p и q.

Рис. 1. Взаимодействие родственных процессов в дуплексном режиме

Порожденный процесс выполняет независимо написанную программу (Count), которая читает данные из входного потока stdin (точка 1) и записывает их в стандартный выходной поток stdout (точка 2), т.е. использует функции getchar() и printf().

#include <stdio.h>

#define R 0 /* stdin */

#define W 1 /* stdout */

#define True 1

#define FALSE 0

#define PERIOD '.'

void main(void) /* Textcount.c */

{

int pid;

int p[2], q[2];

FILE *fdopen(), *fp;

int c;

int newline = TRUE;




int total;

/* Установка программных каналов p и q */

pipe(p);

pipe(q);

/* p[R], q[R] - концы каналов для чтения */

/* p[W], q[W] - концы каналов для записи */

switch(pid = fork())

{

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

/* читает из p[R] */

/* пишет в q[W] */

/* p[W] и q[R] - закрыты */

/* станд. ввод и p[R] - синонимы */

/* станд. вывод и q[W] синонимы */

/* Канал P */

close(p[W]);

close(R); dup(p[R]); close(p[R]);

/* Теперь станд. ввод и p[R] - синонимы */

/* Канал Q */

close(q[R]);

close(W); dup(q[W]); close(q[W]);

/* Теперь станд. вывод и q[W] - синонимы */

/* Запуск внешней независимой программы Count */

execl("count", "count", 0);

printf("textcount: Ошибка при вызове");

exit(1);

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

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

exit(1);

default: /* Это ПРЕДОК */

/* Конец канала P преобразуется для */

/* записи в поток */

close(p[R]); close(q[W]);

fp = fdopen(p[W], "w");

/* Посылка текстового файла в процесс COUNT */ while((c=getchar() != EOF )

{

switch(newline)

{

case TRUE:

if (c == '\n') /* Пустая строка */

putc(c, fp);

else if (c == PERIOD)

/* Пропустить строку */

while((c=getchar() != EOF && c != '\n') ;

else

{

putc(c, fp);

newline = FALSE;

}

break;

default:

putc(c, fp);

if (c == '\n')

newline = TRUE;

}

}

fclose(fp); /* Чтобы принимающий процесс мог воспринимать */

/* EOF на конце канала для чтения */

/* Теперь подключаем ввод результата */

/* из канала Q */

close(R); dup(q[R]); close(q[R]);

scanf("%d", &total);

printf("Общее число знаков %d\n", total);

exit(0);

}

}

/* Независимая программа Count – подсчет символов, полученных от процесса Textcount */

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

/* Процесс, выполняющий COUNT, должен */

/* переназначить ввод и вывод так, */

/* чтобы ввод данных выполнялся из канала P, */

/* а вывод - канал Q */

/* */

{

int count = 0;

while (getchar() != EOF)

count++; printf("%d\n", count);

}







Сейчас читают про: