use*_*082 1 c linux named-pipes fifo cat
我想让两个进程通过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;
}
Run Code Online (Sandbox Code Playgroud)
这是第二个过滤器的代码(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;
}
Run Code Online (Sandbox Code Playgroud)
我编译(gcc -o A a.c && gcc -o B b.c),创建两个fifos(mkfifo b2a ; mkfifo a2b),在终端(cat a2b | ./B > b2a)中运行第一个程序,打开一个新终端并运行第二个程序(cat b2a | ./A > a2b).
我所期待的是A和B依次增加数量的无限循环,但我得到的是B卡住,无法读取A写的内容.
在我推出B的术语中,我得到:
B is going to read
Run Code Online (Sandbox Code Playgroud)
在我发布A的终端中,我得到:
A is going to write
A wrote 1.000000
A is going to read
Run Code Online (Sandbox Code Playgroud)
如果我使用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
Run Code Online (Sandbox Code Playgroud)
为什么我达不到我的预期?
提前致谢.
您需要fflush在写入后明确,以便输出通过管道.否则,输出可能会留在写入过程的stdio缓冲区中.(你也可以用setvbuf(stdio, NULL, _IONBF, 0).关闭缓冲.)