Два фильтра, циклически связанные двумя именованными каналами (FIFO) в Linux - PullRequest
1 голос
/ 25 января 2011

Я хочу, чтобы два процесса взаимодействовали друг с другом через два именованных канала в Linux.Каждый процесс представляет собой фильтр Unix: он считывает данные со своего стандартного ввода и записывает данные в свой стандартный вывод.Они связаны по кругу тем, что выход первого является входом второго и наоборот.

Вот код первого фильтра (ac):

#include <stdio.h>

int main( void  ){
  FILE* ferr = fopen( "/dev/stderr", "w" );
  double d;

  fprintf(ferr,"A is going to write\n");
  printf("%lf\n",1.);
  fprintf(ferr,"A wrote %lf\n",1.);

  while( 1 ){
    fprintf(ferr,"A is going to read\n");
    if( scanf("%lf",&d) == EOF ){
      break;
    }
    fprintf(ferr,"A recieved : %lf\n",d);
    d += 1;
    fprintf(ferr,"A is going to write\n");
    printf("%lf\n",d);
    fprintf(ferr,"A wrote %lf\n",d);
  }
  return 0;
}

Вот код второго фильтра (bc):

#include <stdio.h>

int main( void  ){
  FILE* ferr = fopen( "/dev/stderr", "w" );
  double d;

  while( 1 ){
    fprintf(ferr,"B is going to read\n");
    if( scanf("%lf",&d) == EOF ){
      break;
    }
    fprintf(ferr,"B recieved : %lf\n",d);
    d += 1;
    fprintf(ferr,"B is going to write\n");
    printf("%lf\n",d);
    fprintf(ferr,"B wrote %lf\n",d);
  }
  return 0;
}

Я компилирую (gcc -o A a.c && gcc -o B b.c), создаю два фифа (mkfifo b2a ; mkfifo a2b), запускаю первую программу в терминале (cat a2b | ./B > b2a)откройте новый терминал и запустите вторую программу (cat b2a | ./A > a2b).

То, что я ожидал, было бесконечным циклом с A и B, увеличивающим число по очереди, но я получаю застрявший B, не способныйчитать то, что написал А.

В терминах, где я запустил B, я получаю:

B is going to read

В терминале, где я запустил A, я получаю:

A is going to write
A wrote 1.000000
A is going to read

Если я использую lsof:

lsof b2a a2b
COMMAND   PID      USER   FD   TYPE DEVICE SIZE/OFF      NODE NAME
cat     24382 john doe    3r  FIFO   0,22      0t0 282149936 a2b
B       24383 john doe    1w  FIFO   0,22      0t0 282149934 b2a
cat     24413 john doe    3r  FIFO   0,22      0t0 282149934 b2a
A       24414 john doe    1w  FIFO   0,22      0t0 282149936 a2b

Почему я не получаю то, что ожидал?

Заранее спасибо.

1 Ответ

6 голосов
/ 25 января 2011

Вам нужно явно fflush после записи, чтобы вывод проходил через канал. В противном случае выходные данные могут остаться в буфере stdio процесса записи. (Вы также можете отключить буферизацию с помощью setvbuf(stdio, NULL, _IONBF, 0).)

...