C中的Linux管道
我有以下代码:C中的Linux管道,c,linux,file,pipe,C,Linux,File,Pipe,我有以下代码: #include<stdio.h> FILE *f,*stream1,*stream2,*stream3,*stream4; int main() { int pfd[2]; int pfd1[2]; int pfd2[2]; int pid1; int pid2; pipe(pfd); pipe(pfd1); pipe(pfd2); f=fopen("date","r"); pi
#include<stdio.h>
FILE *f,*stream1,*stream2,*stream3,*stream4;
int main()
{
int pfd[2];
int pfd1[2];
int pfd2[2];
int pid1;
int pid2;
pipe(pfd);
pipe(pfd1);
pipe(pfd2);
f=fopen("date","r");
pid1=fork();
if(pid1==0){
close(pfd[1]);
stream2=fdopen(pfd[0],"r");
char c;
int rd=fread(&c,sizeof(char),1,stream2);
while(rd!=0){
printf("%c",c);
rd=fread(&c,sizeof(char),1,stream2);
}
close(pfd[0]);
exit(0);
}
pid2=fork();
if(pid2==0){
printf("second process\n");
exit(0);
}
if(pid1>0&&pid2>0){
close(pfd[0]);
stream1=fdopen(pfd[1],"w");
while(!feof(f)){
char c;
fscanf(f,"%c",&c);
if(feof(f)) break;
fwrite(&c,sizeof(char),1,stream1);
}
close(pfd[1]);
exit(0);
}
}
#包括
文件*f、*stream1、*stream2、*stream3、*stream4;
int main()
{
int-pfd[2];
int-pfd1[2];
int-pfd2[2];
int-pid1;
int-pid2;
管道(pfd);
管道(pfd1);
管道(pfd2);
f=fopen(“日期”、“r”);
pid1=fork();
如果(pid1==0){
关闭(pfd[1]);
stream2=fdopen(pfd[0],“r”);
字符c;
int-rd=fread(&c,sizeof(char),1,stream2);
而(rd!=0){
printf(“%c”,c);
rd=fread(&c,sizeof(char),1,stream2);
}
关闭(pfd[0]);
出口(0);
}
pid2=fork();
如果(pid2==0){
printf(“第二过程”);
出口(0);
}
如果(pid1>0&&pid2>0){
关闭(pfd[0]);
stream1=fdopen(pfd[1],“w”);
而(!feof(f)){
字符c;
fscanf(f、%c、&c);
如果(feof(f))断裂;
fwrite&c,sizeof(char),1,stream1;
}
关闭(pfd[1]);
出口(0);
}
}
此代码从文件中获取一些输入,并将其显示在child1中。
问题是,每当我想在父进程中关闭pfd[1]
时,child1(pid1
)中的输出都不会显示。为什么会这样?如果我不关闭pfd[1]
它会正常运行
编辑:我解决了。问题是我用fread,fwrite代替了读写。有了它,一切都按我的要求运行。有两个问题: 1) 您使用的是
fdopen
和fwrite
而不是使用write
写入管道
这是可能的,但是fwrite
将在内部调用write
之前缓冲数据
调用fclose(stream1)
时,fclose
函数将首先使用write()
写入所有缓冲数据,然后调用close(pfd[1])
但是,如果直接调用close(pfd[1])
,缓冲数据不会写入管道
2) 当程序完成时,子进程通常也会被终止
在使用fork
创建的所有子进程也完成之前,不要离开main
函数。(使用return
或exit()
并不重要)
使用waitpid
或wait4
函数等待子进程完成
我在我的电脑上编译了这个程序:只有在解决这两个问题时,我才能得到想要的结果。您不应该在父级和子级中调用
exit
。这是一个严重的错误,在过去曾造成严重的安全后果。通常,正确的解决方案是让孩子调用\u exit
。(例如,想象一下,如果您在流程的退出处理程序要执行某些不能多次发生的操作时调用fork
。您是否100%确定所有atfork
处理程序都会解决此问题?如果不是,请不要退出两次。)