CTRL+;D不';t发送到管道C

CTRL+;D不';t发送到管道C,c,C,我有这个节目。当按下ctrl+d(EOF)时,程序从stdin中读取多个数字。正数进入一个子进程,负数进入另一个子进程。我的问题是:为什么EOF不通过管道发送到这两个进程? 这是我的节目: #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <errno.h&

我有这个节目。当按下ctrl+d(EOF)时,程序从stdin中读取多个数字。正数进入一个子进程,负数进入另一个子进程。我的问题是:为什么EOF不通过管道发送到这两个进程? 这是我的节目:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>

int p0top1[2],p0top2[2];

void tataWork()
{
    int nr;
    FILE *fout1, *fout2;
    fout1 = fdopen(p0top1[1], "w");
    fout2 = fdopen(p0top2[1], "w");
    printf("Begin P0\n");
    while(EOF != scanf("%d", &nr))
    {
        if(nr > 0)
        {
            fprintf(fout1,"%d\n", nr);
            fflush(fout1);
        }
        else
        {
            fprintf(fout2,"%d\n", nr);
            fflush(fout2);
        }
    }

    close(p0top1[1]);
    close(p0top2[1]);
    printf("Finish P0\n");
}

void p1Work()
{
    close(p0top1[1]);
    printf("Begin P1\n");
    int nr, i, n = 0, sum = 0, vector[1024];
    FILE *fin;
    fin = fdopen(p0top1[0], "r");

    while(EOF != fscanf(fin, "%d", &nr))
    {
        vector[n++] = nr;
        sum += nr;
    }
    for(i = 0; i < n; i++)
            printf("%d ", vector[i]);
    close(p0top1[0]);
    printf("Finish P1\n");
}

void p2Work()
{
    close(p0top2[1]);
    printf("Begin P2\n");
    int nr, i, n = 0, sum = 0, vector[1024];
    FILE *fin;
    fin = fdopen(p0top2[0], "r");

    while(EOF != fscanf(fin, "%d", &nr))
    {
        vector[n++] = nr;
        sum += nr;
    }
    printf("I am  P2.\n");
    for(i = 0; i < n; i++)
        printf("%d ", vector[i]);
    close(p0top2[0]);
    printf("Finish P2\n");
}

void makePipe()
{
    if(-1 == pipe(p0top1) )
    {
        perror("Error creating the pipe");
        exit(1);
    }

    if(-1 == pipe(p0top2) )
    {
         perror("Error creating the pipe");
         exit(1);
    }

}

int main(void)
{
    pid_t p1, p2;

    makePipe();

    if(-1 == (p1=fork()) )
    {
        perror("Error creating the child");
        exit(3);
    }

    if(p1)
    {
        if(-1 == (p2=fork()) )
        {
            perror("Error creating the child");
            exit(4);
        }

        if(p2)
        {
            tataWork();
        }
        else
        {
            p2Work();
        }
    }
    else
    {
        p1Work();
    }
    return 0;
}
因为EOF没有发送,所以孩子们没有完成?
对不起,我的英语不好

当指向管道写入端的所有
fd
s都关闭时,从管道读取EOF。您的两个管道都有三个写入端副本(一个在主进程中,两个子进程中各有一个)。在您的程序中,您只关闭其中两个。在子进程中,您不会关闭子进程实际不使用的管道(但是,
fork
还是创建了一个副本)

p1工作的开始

close(p0top2[1]);

当所有指向管道写入端的
fd
s关闭时,将从管道读取EOF。您的两个管道都有三个写入端副本(一个在主进程中,两个子进程中各有一个)。在您的程序中,您只关闭其中两个。在子进程中,您不会关闭子进程实际不使用的管道(但是,
fork
还是创建了一个副本)

p1工作的开始

close(p0top2[1]);

p2Work
的开始,你的程序就可以运行了。

看看你的循环状况。我觉得Siguza还可以。。。。你能告诉我我错过了什么吗?Nvm,我看错了。但是:两个子进程仍然保留对另一个子进程管道的写入描述符。他们将写描述符关闭到自己的管道,但不关闭到另一个管道的写描述符。看看循环的条件。Siguza对我来说似乎没问题。。。。你能告诉我我错过了什么吗?Nvm,我看错了。但是:两个子进程仍然保留对另一个子进程管道的写入描述符。他们将写描述符关闭到自己的管道,但不关闭另一个管道的写描述符。它正在工作。。。如果你想回答我,我还有一个问题。。。我想把第一个和第二个孩子的总数发送给父母。。。我该怎么做?我试着用另一根管子,但它不起作用。。。我得到相同的输出。。。我想这是因为新管道,但如果我关闭它,我如何将其发送回父进程?@Marius要将结果从子进程发送回主进程,我会在
fork
s之前在主程序中创建另一对管道。您将在主进程中读取读取端的结果,并在childs中写入写入端。它正在工作。。。如果你想回答我,我还有一个问题。。。我想把第一个和第二个孩子的总数发送给父母。。。我该怎么做?我试着用另一根管子,但它不起作用。。。我得到相同的输出。。。我想这是因为新管道,但如果我关闭它,我如何将其发送回父进程?@Marius要将结果从子进程发送回主进程,我会在
fork
s之前在主程序中创建另一对管道。您将在主进程中读取读取端的结果,并在childs中写入写入端。
close(p0top2[1]);