C-使用管道连续传递两个过程之间的数据



我正在尝试进行两个孩子的过程以通过管道互相交流。

一个孩子应该继续从stdin阅读,将其阅读的内容传递给管道,而另一个孩子应该从管道上读取并将其打印到Stdout中。

我设法使它起作用,但是在阅读数字后的第二次迭代中只有一次,我得到了: write failed: Bad file descriptor

我不知道我在做什么错...

#define READ 0
#define WRITE 1
int main(){
    int pipe_descs[2];
    int retval = pipe(pipe_descs);
    int pid = fork();
    if(pid == 0){   //son that reads from stdin and writes to pipe 
        close(pipe_descs[READ]);
        int x;
        while(1){
            open(pipe_descs[WRITE]);
            scanf("%d", &x);
            if(write(pipe_descs[WRITE], &x, sizeof(int)) != sizeof(int)){
                perror("write failed");
                exit(EXIT_FAILURE);
            }
            close(pipe_descs[WRITE]);
        }
        perror("");
    }
    else if(pid > 0){   //parent
        int pid = fork();
        if(pid == 0){   //son that reads from pipe and write to stdout 
            int pipestat;
            int readNum;
            close(pipe_descs[WRITE]);
            while((pipestat = read(pipe_descs[READ], &readNum, sizeof(int))) > 0){
                printf("read: %d n", readNum);
                //close(pipe_descs[READ]);
                //open(pipe_descs[READ]);
            }
            if (pipestat==-1) {
                perror("");
                fprintf(stderr, "error to pipe... exitingn");
                exit(EXIT_FAILURE);
            }
        }
    }
    int status;
    int i = 2;
    while (i > 0){
        wait(&status);
        i--;
    }
}

问题#1

如果您要关闭作者(close(pipe_descs[WRITE]);),则无法继续使用它!删除该语句,或关闭管道后退出环路。

问题#2

open(pipe_descs[WRITE])毫无意义!摆脱它。

问题#3

[如果您的系统符合POSIX.1-2001,并且您写的金额小于PIPE_BUF,则可以忽略此部分。]

write(..., sizeof(int)) != sizeof(int)(一定)没有指示错误条件。如果没有发生错误,则write没有将errno设置为有意义的事物,因此您获得的错误消息是毫无意义的。

由于write的写入少于请求的金额不是错误,因此需要在A循环中调用它。更换

        if(write(pipe_descs[WRITE], &x, sizeof(int)) != sizeof(int)){
            perror("write failed");
            exit(EXIT_FAILURE);
        }

        my_write(pipe_descs[WRITE], &x, sizeof(x));

并添加

void my_write(int fd, const void *buf, size_t bytes_to_write) {
    while (bytes_to_write > 0) {
        ssize_t bytes_written = write(fd, buf, bytes_to_write);
        if (bytes_written == -1) {
            perror("write failed");
            exit(EXIT_FAILURE);
        }
        buf            += bytes_written;
        bytes_to_write -= bytes_written;
    }
}

类似,read的返回少于请求的金额不是错误。因此,还需要在A循环中调用。更换

        while((pipestat = read(pipe_descs[READ], &readNum, sizeof(int))) > 0){
            printf("read: %d n", readNum);
            //close(pipe_descs[READ]);
            //open(pipe_descs[READ]);
        }
        if (pipestat==-1) {
            perror("");
            fprintf(stderr, "error to pipe... exitingn");
            exit(EXIT_FAILURE);
        }

        while (my_read(pipe_descs[READ], &readNum, sizeof(readNum))) {
            printf("read: %d n", readNum);
        }

并添加

int my_read(int fd, void *buf, size_t bytes_to_read) {
    int has_read = 0;
    while (bytes_to_read > 0) {
        ssize_t bytes_read = read(fd, buf, bytes_to_read);
        if (bytes_read == -1) {
            perror("read failed");
            exit(EXIT_FAILURE);
        }
        if (bytes_read == 0) {
             if (has_read) {
                 fprintf(stderr, "read failed: Premature EOF");
                 exit(EXIT_FAILURE);
             }
             return 0;
        }
        has_read = 1;
        buf           += bytes_read;
        bytes_to_read -= bytes_read;
    }
    return 1;
}

最新更新