简体   繁体   English

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

[英]c-how to read and write at the same time in multiple pipes?

this is just part of my program. 这只是我程序的一部分。

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

so i wrote 10 separate numbers(converted to string) to fd[0][1] in my code in the parent process (i have not showed it here but i know that it works). 所以我在父进程的代码中将10个单独的数字(转换为字符串)写入了fd[0][1] (我在这里没有显示出来,但我知道它可以工作)。 Now, i can only read one data from fd[0][0] . 现在,我只能从fd[0][0]读取一个数据。 if i remove 如果我删除

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

it will read all of the data. 它将读取所有数据。 Why is this interfering with the read?if there are any other improvements in my code that i can make, let me know. 为什么这会干扰阅读?如果我可以对代码进行其他改进,请告诉我。

here is the full code: 这是完整的代码:

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

}

I found the solution.But the credit goes to Barmar for helping me and giving me hints of the possible problems in the comments. 我找到了解决方案,但值得称赞的是Barmar帮助我,并在评论中提示了我可能存在的问题。 The problem as Barmar actually hinted is "you're getting stuck when you write to fd[1][1]. The problem is the process that's reading from fd[1][0]". 正如Barmar实际暗示的那样,问题是“写入fd [1] [1]时卡住了。问题是从fd [1] [0]读取过程。 Apparently, the write terminated the program knowing that there is no other processes to read the data(parent process finished executing or the process reading fd[1][0]).Therefore, Adding wait in the parent process(the other process) would solve the issue. 显然,写操作知道没有其他进程读取数据(父进程完成执行或进程读取fd [1] [0]),从而终止了该程序。因此,在父进程(另一个进程)中添加wait解决问题。

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

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