c-如何在多个管道中同时读写?

时间:2018-07-18 23:51:36

标签: c pipe fork

这只是我程序的一部分。

char temp[100];//stores the temporary value from the pipe read
if(close(fd[0][1])==-1){//closing the write of the first pipe
    perror("Error: closing the write pipe [child]-");
    exit(-1);
}
if(close(fd[1][0])==-1){//closing the read of the second pipe
    perror("Error: closing the write pipe [child]-");
    exit(-1);
}

if(!(read(fd[0][0],temp,10)>0)){//the first number read specifies the overall filter
    fprintf(stderr,"Error: while reading the filter");
    exit(-1);
}
filter=strtol(temp,NULL,10);//storing the first read as the filter
while(read(fd[0][0],temp,10)>0){//reading the rest of the data for filtering
    printf("[%d] child received %s\n",getpid(),temp);
    if(strtol(temp,NULL,10)%filter!=0){//checking to see if the read number is divisible by the filter
        //if not, we write it to the second pipe
        if(write(fd[1][1],temp,10)==-1){
            perror("Error: failed to write to pipe -");
            exit(-1);
        }
    }
}

if(close(fd[1][1])==-1){//closing the write of the second pipe
    perror("Error: closing the read pipe [child]-");
    exit(-1);
}
if(close(fd[0][0])==-1){//closing the read of the first pipe
    perror("Error: closing the read pipe [child]-");
    exit(-1);
}

所以我在父进程的代码中向fd[0][1]写了10个单独的数字(转换为字符串)(我在这里没有显示,但我知道它可以工作)。现在,我只能从fd[0][0]中读取一个数据。如果我删除

if(write(fd[1][1],temp,10)==-1){
    perror("Error: failed to write to pipe -");
    exit(-1);
}

它将读取所有数据。为什么这会干扰阅读?如果我可以对代码进行其他改进,请告诉我。

这是完整的代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
#include <sys/wait.h>

int main(int argc,char*argv[]){
/*---------------Error checking----------------*/
//checking to see if correct number of arguments is provided
if(argc!=2){
    fprintf(stderr, "Usage:\n\tpfact n\n");
    exit(1);
}

//checking to see if correct argument is provided
char *leftOver;
int checkNumber=strtol(argv[1],&leftOver,10);
int squareroot_checkNumber=sqrt((double)checkNumber);
if(leftOver[0]!='\0'){
    fprintf(stderr, "Usage:\n\tpfact n\n");
    exit(1);
}

if(checkNumber<=0){
    fprintf(stderr, "Usage:\n\tpfact n\n");
    exit(1);
}
/*-------------------------------------------*/
char factors[checkNumber-1][100];
int factor_size=0;
strcpy(factors[0],"-1");
int child;
int number_process=0;//keeps track of number of processes created
int isInitialized=0;//sees if we are initialized yet or not
int filter;//stores the number used to filter the data

int fd[2][2];

//create the two pipes
if(pipe(fd[0]) == -1){
    perror("Error: creating a pipe -");
}

if(pipe(fd[1]) == -1){
    perror("Error: creating a pipe -");
}
do{
    child=fork();
    if(child<0){
        perror("Error: making a child -");
        exit(1);
    }

    if(child>0){
        if(isInitialized==0){//not initialized yet //no data has been written to the pipe
            isInitialized=1;//it has been initilized now
            if(close(fd[0][0])==-1){//closing the read of the first pipe
                perror("Error: closing the read pipe [parent]-");
                exit(-1);
            }
            //writing 2 to m to the pipe
            for(int i=2;i<=checkNumber;i++){
                char number_string[100];
                sprintf(number_string,"%d",i);
                if(write(fd[0][1],number_string,10)==-1){
                    perror("Error: failed to write to pipe -");
                    exit(-1);
                }
            }
            if(close(fd[0][1])==-1){//closing the write of the first pipe after finishing writing
                perror("Error: closing the write pipe [parent]-");
                exit(-1);
            }
        }else{
            char temp_parent[100];//stores the temporary value from the pipe read
            if(close(fd[0][0])==-1){//closing the read of the first pipe
                perror("Error: closing the write first pipe [parent]-");
                exit(-1);
            }
            if(close(fd[1][1])==-1){//closing the write of the second pipe
                perror("Error: closing the write second pipe [parent]-");
                exit(-1);
            }

            while(read(fd[1][0],temp_parent,10)>0){//reading the data from the second pipe
                //write the data to the first pipe so that it can be read by the child for filtering
                if(write(fd[0][1],temp_parent,10)==-1){
                    perror("Error: failed to write to pipe -");
                    exit(-1);
                }
                printf("[%d] parent received %s\n",getpid(),temp_parent);
            }


            if(close(fd[0][1])==-1){//closing the write of the first pipe
                perror("Error: closing the read first pipe [parent]-");
                exit(-1);
            }
            if(close(fd[1][0])==-1){//closing the read of the second pipe
                perror("Error: closing the read second pipe [parent]-");
                exit(-1);
            }
        }
    }else if(child==0){

        char temp[100];//stores the temporary value from the pipe read
        if(close(fd[0][1])==-1){//closing the write of the first pipe
            perror("Error: closing the write pipe [child]-");
            exit(-1);
        }
        if(close(fd[1][0])==-1){//closing the read of the second pipe
            perror("Error: closing the write pipe [child]-");
            exit(-1);
        }

        if(!(read(fd[0][0],temp,10)>0)){//the first number read specifies the overall filter
            fprintf(stderr,"Error: while reading the filter");
            exit(-1);
        }
        filter=strtol(temp,NULL,10);//storing the first read as the filter
        while(read(fd[0][0],temp,10)>0){//reading the rest of the data for filtering
            printf("[%d] child received %s\n",getpid(),temp);
            if(strtol(temp,NULL,10)%filter!=0){//checking to see if the read number is divisible by the filter
                //if not, we write it to the second pipe
                if(write(fd[1][1],temp,10)==-1){
                    perror("Error: failed to write to pipe -");
                    exit(-1);
                }
            }
        }

        if(close(fd[1][1])==-1){//closing the write of the second pipe
            perror("Error: closing the read pipe [child]-");
            exit(-1);
        }
        if(close(fd[0][0])==-1){//closing the read of the first pipe
            perror("Error: closing the read pipe [child]-");
            exit(-1);
        }
    }
}while(0 && child==0 && checkNumber/2<=filter);

}

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。但值得称赞的是Barmar帮助我,并在注释中给了我一些可能的问题的提示。正如Barmar实际暗示的那样,问题是“写入fd [1] [1]时卡住了。问题是从fd [1] [0]读取过程。显然,写操作知道没有其他进程读取数据(父进程完成执行或进程读取fd [1] [0]),从而终止了该程序。因此,在父进程(另一个进程)中添加wait解决问题。