Почему эта функция производит так много дочерних процессов? - PullRequest
0 голосов
/ 21 марта 2019

Я написал этот код для вычисления факториала числа с использованием процессов и pipe(). Я хотел передать результат от дочернего процесса к дочернему процессу. Например, для создания расчета 5! главный, который является отцом, посылает номер 1 в трубу. Затем создается первый дочерний элемент и выполняется 1 * 2, затем он вставляет в канал число 2, второй дочерний элемент 2 * 3 передает результат в канал и т. Д. Кроме того, я использую argv [1] [0] думая, что мы запускаем программу следующим образом (./ex3 5), где 5 - это число, которое мы хотели бы найти. Однако после запуска программы я заметил, что было создано много дочерних процессов (я хотел только 4) . Почему это?

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

int fd[2];
int w,count=2;

void child_creator(){
    pid_t child;
    child=fork();
    if (child==0) {
        close(fd[1]);
        read(fd[0],&w,sizeof(w));
        close(fd[0]);
        w=w*count;
        count++;
        printf("I am child %d , my father is %d , the prod is %d\n",getpid(),getppid(),w);
        sleep(1);

        close(fd[0]);
        write(fd[1],&w,sizeof(w));
        close(fd[1]);       
    }
}       

int main(int argc , char **argv){
    int fact=argv[1][0]-'0';
    pipe(fd);
    w=1;
    for (int i=0; i<fact-1; i++){
         printf("this is i %d\n", i);
        child_creator();
    }
    return 0;
}   

После предложенного ответа я попробовал этот код:

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

int fd[1000][2];
int w,count=1,j=0;

void child_creator(){
    pid_t child;
    j++;
    pipe(fd[j]);
    child=fork();
    if (child==0) {
        close(fd[j-1][1]);
        read(fd[j-1][0],&w,sizeof(w));
        close(fd[j-1][0]);
        w=w*count;
        printf("I am child %d , my father is %d , the prod is %d\n",getpid(),getppid(),w);
        sleep(1);

        close(fd[j-1][0]);
        write(fd[j][1],&w,sizeof(w));
        close(fd[j][1]);

        exit(0);        

    }

}       

int main(int argc , char **argv){
    int fact=argv[1][0]-'0';
    w=1;
    for (int i=0; i<fact-1; i++){ 
     count++;
     child_creator();
     sleep(2);
    }

    return 0;
}   

1 Ответ

1 голос
/ 21 марта 2019

И родитель, и ребенок возвращаются в цикл for в main().Поскольку дочернему элементу не нужно ничего делать после того, как он записывает свой результат, он должен просто выйти, а не вернуться.

У вас также есть проблемы с обработкой дескрипторов файла канала.Вы делаете close(fd[1]) в начале ребенка, но позже попробуйте write(fd[1],&w,sizeof(w)).Вы не можете писать в закрытый FD.Вам не нужно ничего закрывать, пока дочерний процесс не завершится, и выход из процесса автоматически закроет все его файлы.

void child_creator(){
    pid_t child;
    child=fork();
    if (child==0) {
        read(fd[0],&w,sizeof(w));
        w=w*count;
        count++;
        printf("I am child %d , my father is %d , the prod is %d\n",getpid(),getppid(),w);
        sleep(1);
        write(fd[1],&w,sizeof(w));
        exit(0);   
    }
}       
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...