简体   繁体   English

C语言中的Linux管道

[英]Linux pipes in C

I have the following code: 我有以下代码:

#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);
    }
}

This code takes some input from a file and displays it in child1. 此代码从文件中获取一些输入,并将其显示在child1中。 The problem is that whenever I want to close pfd[1] in the parent process, the output in child1 ( pid1 ) doesn't show up. 问题是,每当我想在父进程中关闭pfd[1]时, pid1pid1 )中的输出都不会显示。 Why is this happening? 为什么会这样呢? If I don't close pfd[1] it goes normally. 如果我不关闭pfd[1]它将正常运行。

Edit: I solve it .The problem was that i used fread,fwrite instead of read and write. 编辑:我解决了。问题是我用fread,fwrite代替了读写。 With this in place everything runs as i wanted. 有了这个适当的地方,一切都会按照我的意愿运行。

There are two problems: 有两个问题:

1) You are using fdopen and fwrite instead of writing to the pipe using write . 1)您正在使用fdopenfwrite而不是使用write管道。

This is possible however fwrite will buffer the data before calling write internally. 这是可能的,但是fwrite将在内部调用write之前缓冲数据。

When you call fclose(stream1) the fclose function will first write all buffered data using write() and then call close(pfd[1]) . 当您调用fclose(stream1)fclose函数将首先使用write()写入所有缓冲的数据,然后调用close(pfd[1])

However if you call close(pfd[1]) directly the buffered data is not written to the pipe. 但是,如果直接调用close(pfd[1]) ,则缓冲的数据不会写入管道。

2) When a program finishes child processes are typically also killed. 2)当程序完成时,通常也会杀死子进程。

Don't leave the main function until all child processes created using fork also have finished. 在使用fork创建的所有子进程也都完成之前,请不要离开main函数。 (It does not matter if you use return or exit() ). (使用returnexit()都没有关系。

Use the waitpid or the wait4 function to wait for a child process to finish. 使用waitpidwait4函数等待子进程完成。

I compiled the program on my computer: Only when fixing both problems I get the desired result. 我在计算机上编译了该程序:只有同时解决了两个问题,我才能得到预期的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM