【问题标题】:c-how to read and write at the same time in multiple pipes?c-如何在多个管道中同时读写?
【发布时间】:2018-07-18 23:51:36
【问题描述】:

这只是我的程序的一部分。

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

所以我在父进程的代码中将 10 个单独的数字(转换为字符串)写入fd[0][1](我没有在这里展示它,但我知道它有效)。现在,我只能从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);

}

【问题讨论】:

  • 我不想使用数组。我只想直接读写管道
  • read() 不会以空值终止数据,您无法使用%s 格式打印它。
  • 如果你们愿意,我可以发布完整的代码
  • 是否有从第二个管道读取的进程?如果没有,如果第二个管道已填满,您可能会阻塞。
  • 这是个问题。管道的容量是有限的,所以如果写入器领先于读取器太远,它就会被阻塞,直到读取器赶上。

标签: c pipe fork


【解决方案1】:

我找到了解决方案。但要感谢 Barmar 帮助我并提示我在 cmets 中可能存在的问题。 Barmar 实际上暗示的问题是“当您写入 fd[1][1] 时,您遇到了困难。问题是从 fd[1][0] 读取的过程”。显然,在知道没有其他进程读取数据(父进程完成执行或正在读取 fd[1][0] 的进程)的情况下,写入终止了程序。因此,在父进程(其他进程)中添加等待将解决问题。

【讨论】:

  • 我不确定确切的技术事件或问题的终止。这只是我预期的行为
猜你喜欢
  • 1970-01-01
  • 2011-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-04
  • 2013-01-29
  • 2011-05-28
相关资源
最近更新 更多