Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中的Linux管道_C_Linux_File_Pipe - Fatal编程技术网

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
处理程序都会解决此问题?如果不是,请不要退出
两次。)