C中的管道-在我的程序中读写

C中的管道-在我的程序中读写,c,pipe,C,Pipe,我希望我的程序显示如下结果: child: 2 4 6 8 10 parent: 3 6 9 12 15 child 12 14 16 18 20 parent 18 21 24 27 30 #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(void) { int i = 0, tube1[2], tube2[2], pid; if (pi

我希望我的程序显示如下结果:

child: 2 4 6 8 10  
parent: 3 6 9 12 15  
child 12 14 16 18 20  
parent 18 21 24 27 30  
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    int i = 0, tube1[2], tube2[2], pid;
    if (pipe(tube1) == -1 || pipe(tube2) == -1)
    {
        perror("pipe");
        exit(0);
    }
    pid = fork();

    while (i < 100)
    {
        if (pid == 0)
        {
            printf("fils ");
            do
            {
                i = i + 2;
                printf("%d ", i);
            } while (i % 5 != 0);
            putchar('\n');

            write(tube1[1], &i, sizeof(int));
            read(tube2[0], &i, sizeof(int));
        }
        else
        {
            printf("pere ");
            read(tube1[0], &i, sizeof(int));
            do
            {
                i = i + 3;
                printf("%d ", i);
            } while (i % 5 != 0);
            putchar('\n');

            write(tube2[1], &i, sizeof(int));
        }
    }
    close(tube1[1]);
    close(tube1[0]);
    close(tube2[1]);
    close(tube2[0]);
}


但是我的程序有问题;我不明白为什么。

清理后,您的代码如下所示:

child: 2 4 6 8 10  
parent: 3 6 9 12 15  
child 12 14 16 18 20  
parent 18 21 24 27 30  
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    int i = 0, tube1[2], tube2[2], pid;
    if (pipe(tube1) == -1 || pipe(tube2) == -1)
    {
        perror("pipe");
        exit(0);
    }
    pid = fork();

    while (i < 100)
    {
        if (pid == 0)
        {
            printf("fils ");
            do
            {
                i = i + 2;
                printf("%d ", i);
            } while (i % 5 != 0);
            putchar('\n');

            write(tube1[1], &i, sizeof(int));
            read(tube2[0], &i, sizeof(int));
        }
        else
        {
            printf("pere ");
            read(tube1[0], &i, sizeof(int));
            do
            {
                i = i + 3;
                printf("%d ", i);
            } while (i % 5 != 0);
            putchar('\n');

            write(tube2[1], &i, sizeof(int));
        }
    }
    close(tube1[1]);
    close(tube1[0]);
    close(tube2[1]);
    close(tube2[0]);
}
您可以看到,子对象生成的值为10;然后父级将从子级接收到的值加上3,即13,并进行迭代;然后它将25发送给子对象,子对象将2和27相加并进行迭代;等等

要获得所寻求的结果,需要将同步中使用的值与控制循环的值解耦。您还面临一个问题,因为子级将尝试比父级运行更长的时间,但幸运的是,当它尝试写入父级已关闭的管道时,它将收到SIGPIPE信号,并将死亡——或者更确切地说,如果它已关闭其未使用的管道末端,它将死亡。在生成换行后刷新标准输出也是一个好主意。这些变化导致:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    int i = 0, tube1[2], tube2[2], pid;
    if (pipe(tube1) == -1 || pipe(tube2) == -1)
    {
        perror("pipe");
        exit(1);
    }
    pid = fork();
    if (pid < 0)
    {
        perror("fork");
        exit(1);
    }
    if (pid == 0)
    {
        close(tube1[0]);
        close(tube2[1]);
    }
    else
    {
        close(tube1[1]);
        close(tube2[0]);
    }

    while (i < 100)
    {
        if (pid == 0)
        {
            printf("fils ");
            do
            {
                i = i + 2;
                printf("%d ", i);
            } while (i % 5 != 0);
            putchar('\n');
            fflush(stdout);

            int j = 0;
            write(tube1[1], &j, sizeof(int));
            read(tube2[0], &j, sizeof(int));
        }
        else
        {
            int j = 0;
            read(tube1[0], &j, sizeof(int));

            printf("pere ");
            do
            {
                i = i + 3;
                printf("%d ", i);
            } while (i % 5 != 0);
            putchar('\n');
            fflush(stdout);

            write(tube2[1], &j, sizeof(int));
        }
    }
    close(tube1[1]);
    close(tube1[0]);
    close(tube2[1]);
    close(tube2[0]);
}
注意,子循环没有达到100是因为父循环退出,而父循环超过100是因为检查发生在外循环,而不是内循环


我保留了您的循环组织,但如果它是我自己的代码,它将有两个函数——be_childish和be_parental——在fork之后调用,每个函数都将运行自己的相关循环。管道将被传递到函数,它们将“更好”地清理。请注意,程序结束时的4个关闭调用中有2个将失败,因为这些管道描述符以前已关闭。分清哪一个是精细的;最好将代码拆分为函数。

这一行的作用与您认为的不同:ifpipetube1 | | pipetube2==-1{@slugonamission:行是自不一致的,这是错误的,但它确实可以工作,因为管道返回一个非零值-失败时为1,成功时为0,因此,如果第一个管道失败,第一个测试将触发if语句体,就像第二个管道失败时第二个测试将触发主体一样und操作符使其可读编译时包含所有警告和调试信息:gcc-Wall-Wextra-g with
fils 2 4 6 8 10 
pere 3 6 9 12 15 
fils 12 14 16 18 20 
pere 18 21 24 27 30 
fils 22 24 26 28 30 
pere 33 36 39 42 45 
fils 32 34 36 38 40 
pere 48 51 54 57 60 
fils 42 44 46 48 50 
pere 63 66 69 72 75 
fils 52 54 56 58 60 
pere 78 81 84 87 90 
fils 62 64 66 68 70 
pere 93 96 99 102 105 
fils 72 74 76 78 80