子进程等待另一个完成,而main()不执行到最后

时间:2018-06-07 12:24:30

标签: c linux pipe fork

xxx 4个子进程处理时,我在第一个子进程执行后进入zzz,而下一个进程甚至没有被执行。我不确定为什么会出现这种现象。我不是分叉的专家,每一个小费都受到赞赏。

fork()

这是我的代码:

wait()

整个过程尝试使用子进程计算Input data: ./forkexample 2 3 4 5 。在编译和运行之后,此序列运行:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, const char **argv)
{

    if (argc != 5)
    {
        printf("Argument # is invalid. %s < 4\n", argv[0]);
        exit(1);
    }

    float a = atof(argv[1]);

    float b = atof(argv[2]);

    float c = atof(argv[3]);

    float d = atof(argv[4]);

    if ((a == 0.0) || (b == 0.0) || (c == 0.0) || (d == 0.0))
    {
        printf("Conversion error, invalid parameters!\n");
        exit(1);
    }

    int ossz[2], kiv[2], szor[2], oszt[2];
    int mainpid;
    if ((pipe(ossz) < 0))
        perror("pipe error(/)");
    if ((pipe(kiv) < 0))
        perror("pipe error(*)");
    if ((pipe(szor) < 0))
        perror("pipe error(-)");
    if ((pipe(oszt) < 0))
        perror("pipe error(*)");

    mainpid = getpid();

    pid_t osszeg, kivonas, szorzat, hanyados;

    //            (a+b*c) / (a-b+d-c) + a*b*c*d;

    //       *****************************+***********************************

    if ((osszeg = fork()) == 0)
    {
        if (mainpid != getpid())
        { //osszeadast vegez el
            float b1, c1, byteb1, bytec1;
            byteb1 = read(ossz[0], &b1, sizeof(float));
            printf("%d  Osszeg read in %.2f\n", getpid(), b1);

            bytec1 = read(ossz[0], &c1, sizeof(float));
            printf("%d Osszeg read in %.2f\n", getpid(), c1);
            close(ossz[0]);
            c1 += b1;

            write(ossz[1], &c1, sizeof(float));
            printf("%d Osszeadas wrote %.2f\n", getpid(), c1);
        }
        else if (getpid() < 0)
        {
            printf("Error creating children process, cprog stops!\n");
            exit(1);
        }
    }

    //       *****************************-***********************************

    if ((kivonas = fork()) == 0)
    {
        if (mainpid != getpid())
        { //kivonast vegez el
            float b2, c2, byteb2, bytec2;
            byteb2 = read(kiv[0], &b2, sizeof(float));
            printf("%d Kivonas read in %.2f\n", getpid(), b2);

            bytec2 = read(kiv[0], &c2, sizeof(float));
            printf("%d Kivonas read in %.2f\n", getpid(), c2);
            close(kiv[0]);
            c2 -= b2;

            write(kiv[1], &c2, sizeof(float));
            printf("%d Kivonas wrote %.2f\n", getpid(), c2);
        }
        else if (getpid() < 0)
        {
            printf("Error creating children process, cprog stops!\n");
            exit(1);
        }
    }
    //       ***************************** Multiplication***********************************

    if ((szorzat = fork()) == 0)
    {
        if (mainpid != getpid())
        { //szorzast vegez el
            float b3, c3, byteb3, bytec3;
            byteb3 = read(szor[0], &b3, sizeof(float));
            printf("%d Szorzat read in %.2f\n", getpid(), b3);

            bytec3 = read(szor[0], &c3, sizeof(float));
            printf("%d Szorzat read in %.2f\n", getpid(), c3);
            close(szor[0]);
            c3 *= b3;

            write(szor[1], &c3, sizeof(float));
            printf("%d Szorzat wrote %.2f\n", getpid(), c3);
        }
        else if (getpid() < 0)
        {
            printf("Error creating children process, cprog stops!\n");
        }
    }

    //       *****************************Division***********************************

    if ((hanyados = fork()) == 0)
    {
        if (mainpid != getpid())
        { //osztast vegez el
            float b4, c4, byteb4, bytec4;
            byteb4 = read(oszt[0], &b4, sizeof(float));
            printf("%d Oszto read in %.2f\n", getpid(), b4);

            bytec4 = read(oszt[0], &c4, sizeof(float));
            printf("%d Oszto read in %.2f\n", getpid(), c4);
            close(oszt[0]);
            c4 = c4 / b4;

            write(oszt[1], &c4, sizeof(float));
            printf("%d Oszto wrote %.2f\n", getpid(), c4);
        }
        else if (getpid() < 0)
        {
            printf("Error creating children process, cprog stops!\n");
            exit(1);
        }
    }

    float szorzaser, osztaser, kivonaser, osszeger, vegeredmeny;
    write(szor[1], &b, sizeof(float));
    write(szor[1], &c, sizeof(float));
    wait(NULL);
    read(szor[0], &szorzaser, sizeof(float)); //b*c
    printf("%d Parent got: %.2f /n", getpid(), szorzaser);

    write(ossz[1], &a, sizeof(float));
    write(ossz[1], &szorzaser, sizeof(float));
    wait(NULL);
    read(ossz[0], &osszeger, sizeof(float)); //a+szorzaser(b*c)
    printf("%d Parent got: %.2f /n", getpid(), osszeger);

    //***********************a+b*c**********************************************

    write(ossz[1], &b, sizeof(float));
    write(ossz[1], &d, sizeof(float));
    wait(NULL);

    read(ossz[0], &osszeger, sizeof(float)); //b+d
    printf("%d Parent got: %.2f /n", getpid(), osszeger);
    write(kiv[1], &a, sizeof(float));
    write(kiv[1], &osszeger, sizeof(float));
    wait(NULL);

    read(kiv[0], &kivonaser, sizeof(float)); //a-osszeger(b+d)
    printf("%d Paren  t got: %.2f /n", getpid(), kivonaser);
    write(kiv[1], &kivonaser, sizeof(float));
    write(kiv[1], &c, sizeof(float));
    wait(NULL);

    read(kiv[0], &kivonaser, sizeof(float)); //kivonaser(a-b+d-c)
    printf("%d Parent got: %.2f /n", getpid(), kivonaser);
    write(oszt[1], &kivonaser, sizeof(float));
    write(oszt[1], &osszeger, sizeof(float)); //betesszuk az osztas pipejaba
    wait(NULL);

    read(oszt[0], &osztaser, sizeof(float)); //(a+b*c) / (a-b+d-c)
    printf("%d Parent got: %.2f /n", getpid(), osztaser);

    //*************************(a-b+d-c)*********************************************

    write(szor[1], &a, sizeof(float));
    write(szor[1], &b, sizeof(float));
    wait(NULL);
    read(szor[0], &szorzaser, sizeof(float)); //a*b
    printf("%d Parent got: %.2f /n", getpid(), szorzaser);

    write(szor[1], &szorzaser, sizeof(float));
    write(szor[1], &c, sizeof(float));
    wait(NULL);
    read(szor[0], &szorzaser, sizeof(float)); //a*b*c
    printf("%d Parent got: %.2f /n", getpid(), szorzaser);

    write(szor[1], &szorzaser, sizeof(float));
    write(szor[1], &c, sizeof(float));
    wait(NULL);
    read(szor[0], &szorzaser, sizeof(float)); //a*b*c*d
    printf("%d Parent got: %.2f /n", getpid(), szorzaser);
    //************************* a*b*c*d *********************************************
    write(ossz[1], &osztaser, sizeof(float));
    write(ossz[1], &szorzaser, sizeof(float));
    wait(NULL);
    read(ossz[0], &vegeredmeny, sizeof(float)); //(a+b*c) / (a-b+d-c)+ a*b*c*d;
    printf("%d Parent got: %.2f /n", getpid(), vegeredmeny);

    close(ossz[0]);
    close(ossz[1]);
    close(kiv[0]);
    close(kiv[1]);
    close(szor[0]);
    close(szor[1]);
    close(oszt[0]);
    close(oszt[1]);

    printf("%d got the final result: %.2f!\n", getpid(), vegeredmeny);
    return (0);
}

在此之后,计算会等待某些事情,我无法弄清楚原因。

1 个答案:

答案 0 :(得分:1)

您的子进程不会退出,而是继续运行用于父进程的代码。因此,在第一个子项将其结果写入管道后,它会开始分支另一个子进程,然后再次写入其自己的管道并输入wait()。然后你有一个死锁 - 父进程等待第一个孩子退出,第一个孩子等待孩子退出。

您也不会检查任何write()来电时的错误情况。如果你这样做,你会看到正在进行意外的write()通话。

向子路径添加_exit()调用应该会有所帮助,但此代码中还有许多其他问题。