c - 从多个管道读取数据的正确方法是什么?

标签 c fork pipe

所以在我的程序中,用户给出了三个参数。然后,我将其传递给三个 child 。

两个 child 各自计算,然后退出。最后一个子项显示结果。

父进程等待所有子进程完成,然后简单地终止程序。

children 所做的事情的总结:

inputs are a, b, c.
child0: c0 = a*b
child1: c1 = b*c
overview: printf("%d %d", c0, c1);

我不知道如何正确打印概述。它不断打印出奇怪的损坏字符或框。

有人对如何正确执行此操作有任何建议吗?我读过一本书,但它只详细介绍了单亲 child 的管道。这涉及多个 child ,我想这就是我感到困惑的地方。感谢您的帮助!

代码如下:

int main(int argc, char *argv[]) {
    int fd[4];
    int a, b, c, c0, c1, status;
    char char0[10];
    char char1[10];
    pid_t child0;
    pid_t child1;
    pid_t overview;

    // Set argv to ints
    a = atoi(argv[1]);
    b = atoi(argv[2]);
    c = atoi(argv[3]);

    // Pipe
    pipe(fd);

    // child0
    if((child0 = fork()) == 0) {
        close(fd[2]);
        c0 = a*b;
        sprintf(char0, "%d", c0);
        write(fd[0], char0, 10);
        close(fd[0]);
        exit(0);
    }

    // child1
    if((child1 = fork()) == 0) {
        close(fd[2]);
        c1 = b*c;
        sprintf(char1, "%d", c1);
        write(fd[1], char1, 10);
        close(fd[1]);
        exit(0);
    }

    // overview
    if((overview = fork()) == 0) {
        close(fd[0]);
        close(fd[1]);
        read(fd[2], char0, 10);
        read(fd[2], char1, 10);
        printf("%s %s", char0, char1); //Prints weird stuff??
        close(fd[2]);
        exit(0);
    }

    // Wait for children to finish
    waitpid(child0, &status, 0);
    waitpid(child1, &status, 0);
    waitpid(overview, &status, 0);
    exit(0);
}

最佳答案

您用于声明管道的代码完全错误,管道只有两端,而对于声明三个管道,您需要声明如下

pd1[2];
pd2[2];
pd3[2];

从一端你可以写成pd1[1];

从另一端您可以读取pd1[0];

所以你的代码看起来像,

int main(int argc, char *argv[]) {
    int fd1[2];
    int fd2[2];
    int fd1[2];        
    int a, b, c, c0, c1, status;
    char char0[10];
    char char1[10];
    pid_t child0;
    pid_t child1;
    pid_t overview;

    // Set argv to ints
    a = atoi(argv[1]);
    b = atoi(argv[2]);
    c = atoi(argv[3]);

    // Pipe
    pipe(fd1);
    pipe(fd2);
    pipe(fd3);
    // child0
    if((child0 = fork()) == 0) {
        close(fd1[0]);
        c0 = a*b;
        sprintf(char0, "%d", c0);
        write(fd1[1], char0, 10);
        close(fd[1]);
        exit(0);
    }

    // child1
    if((child1 = fork()) == 0) {
        close(fd2[0]);
        c1 = b*c;
        sprintf(char1, "%d", c1);
        write(fd2[1], char1, 10);
        close(fd2[1]);
        exit(0);
    }

    // overview
    if((overview = fork()) == 0) {
        close(fd1[1]);
        close(fd2[1]);
        read(fd1[0], char0, 10);
        read(fd2[0], char1, 10);
        printf("%s %s", char0, char1); //Prints weird stuff??
        //close(fd[2]);
        exit(0);
    }

    // Wait for children to finish
    waitpid(child0, &status, 0);
    waitpid(child1, &status, 0);
    waitpid(overview, &status, 0);
    exit(0);
}

这段代码也可能不正确我刚刚解释了如何使用管道,请参阅管道的打开和关闭,即在写入时应关闭读取端,在读取时应关闭写入端。

编辑

看这篇文章,执行小程序,然后一步一步修改你的代码,你就会明白。

How to send a simple string between two programs using pipes?

关于c - 从多个管道读取数据的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26013126/

相关文章:

c - 如何中断一个进程并稍后继续?

c - fork 和 execve 的问题

c - Linux在父进程和子进程之间使用c中的两个管道传递值?

Linux 命令行语法 - 在 ping 请求后管道输入命令

c - 树重建函数中的指针

c - 在 Linux C 中交替同步两个进程

c++ - 如何确保 SqLite 中的只读事务?

c - 有没有办法在 C 中按多个变量对结构进行排序?

PHP mysqli 重新连接问题

bash - 尾-F log.log | grep 响应时间 |切-d = -f 2