一个孩子的管道stdout到c的另一个孩子的stdin

时间:2017-11-21 10:48:02

标签: c pipe dup2

这就是我尝试做的事情:父进程创建两个子进程,然后将stdout的一个stdout传递给另一个进程的stdin。然后父母等待5秒并杀死第一个孩子。

这就是我接近它的方式:首先我创建一个管道。然后fork来创建第一个子节点(gen代码)和dup2来复制管道写入stdout。第二个子句的另一个fork(在代码中称为cons),dup2将读取结束复制到stdin。缺点只是打印数据。父母将SIGTERM发送给第一个孩子,第二个孩子读到EOF,所以它关闭了它自己。

只打印我的错误输出(此处用于调试)。 Gen生成两个随机数,但cons的循环不会被执行。因此,我认为缺点是没有任何缺陷。 我咨询了谷歌,并遵循了这个How do I chain stdout in one child process to stdin in another child in C?,但没有设法弄清楚我搞砸了什么。非常感谢任何帮助。感谢

编译:在Windows 10中的Bash上编译gcc -std=c99 -Wall -Werror main.c -o main

代码:

#define _POSIX_SOURCE
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <signal.h>

#define READ_END 0
#define WRITE_END 1
#define BUF_SIZE 10

int main(int argc, char* argv[])
{
    pid_t gen, cons;
    int fd[2];

    if (pipe(fd) < 0) {
        // pipe error
        exit(1);
    }

    gen = fork();

    if (gen < 0) {
        // fork error
        close(fd[READ_END]);
        close(fd[WRITE_END]);
        exit(2);
    } else if (gen == 0) {
        // gen child
        close(fd[READ_END]);
        time_t t;
        srand((unsigned)time(&t));
        dup2(fd[WRITE_END], STDOUT_FILENO);
        close(fd[WRITE_END]);
        while(1) {
            int a = rand() % 1000;
            int b = rand() % 1000;
            printf("gen %d %d\n", a, b);
            fprintf(stderr, "err, gen %d %d\n", a, b);
            sleep(1);
        }
    }
    else {
        cons = fork();
        if (cons < 0) {
                // fork error
            close(fd[READ_END]);
            close(fd[WRITE_END]);
            kill(gen, SIGKILL);
            exit(2);
        } else if (cons == 0) {
            // cons child
            close(fd[WRITE_END]);
            dup2(fd[READ_END], STDIN_FILENO);
            close(fd[READ_END]);
            char line[BUF_SIZE];
            while (fgets(line, sizeof(line), stdin)) {
                printf("cons received: %s\n", line);
                fprintf(stderr, "cons lives!\n");
            }
        } else {
            // parent
            close(fd[READ_END]);
            close(fd[WRITE_END]);
            sleep(5);
            kill(gen, SIGTERM);
        }
    }
    return 0;
}

1 个答案:

答案 0 :(得分:1)

默认情况下,标准输出是缓冲的,因此您的gen子队列只会将输出排队等待以后发送。因此,您必须fflush强制传递您的信息:

        ...
        printf("gen %d %d\n", a, b);
        fprintf(stderr, "err, gen %d %d\n", a, b);
        fflush(stdout);             // <= force immediate send
        sleep(1);
        ...