дочерний процесс ожидает завершения другого, а main () не выполняется до конца - PullRequest
0 голосов
/ 07 июня 2018

Пока fork() обрабатывает 4 дочерних процесса, я попадаю в 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);
}

Весь процесс пытается вычислить (a+b*c)/(a-b+d-c)+a*b*c*d, используя дочерние процессы,После компиляции и запуска эта последовательность запускается:

vargaelod23@vargaelod23-M5400:~/LinuxI/fork$ ./fork1 2 3 4 5

5459 Szorzat read in 3.00

5459 Szorzat read in 4.00

5459 Szorzat wrote 12.00

После этого вычисления чего-то ждут, и я не могу понять, почему.

1 Ответ

0 голосов
/ 07 июня 2018

Ваши дочерние процессы не завершаются, но продолжают выполнять код, предназначенный для родительского процесса.Таким образом, после того, как первый дочерний элемент записывает свой результат в канал, он начинает разветвлять другие подпроцессы, а затем снова записывает данные в свой собственный канал и вводит wait().Затем возникает тупик - родительский процесс ожидает выхода первого дочернего элемента, а первый дочерний процесс ожидает выхода своего дочернего элемента.

Вы также не проверяете состояние ошибки ни в одном из вызовов write().,Если вы это сделаете, вы увидите, что происходит неожиданный вызов write().

Добавление _exit() вызовов к дочерним путям должно помочь, но в этом коде есть много других неправильных вещей.

...