1

我想让两个进程通过 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),创建两个 fifo ( mkfifo b2a ; mkfifo a2b),在终端 ( ) 中运行第一个程序cat a2b | ./B > b2a,打开一个新终端并运行第二个程序 ( cat b2a | ./A > a2b)。

我期望的是 A 和 B 依次增加数字的无限循环,但我得到的是 B 卡住了,无法阅读 A 写的内容。

在我推出 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

为什么我没有得到我所期望的?

提前致谢。

4

1 回答 1

6

您需要fflush在编写后明确说明,以便输出通过管道。否则,输出可能会留在写入进程的stdio缓冲区中。(您也可以使用 关闭缓冲setvbuf(stdio, NULL, _IONBF, 0)。)

于 2011-01-25T14:52:46.280 回答