Процесс внука имеет PID 1 в C - PullRequest
1 голос
/ 08 февраля 2020

Я пытаюсь передать данные от родителя к ребенку, а затем от ребенка к внуку с помощью трубок. После этого внук отправляет результат родителю обратно, и родитель убивает оба процесса.

Я могу выполнять передачу данных с помощью каналов, но, думаю, я не могу завершить процессы, потому что PID внука рассматривается родителем как 1.

Вот мой код:

int main(){

    if (pipe(fd) == -1) {
        fprintf(stderr,"Pipe failed fd");
        return 1;
    }

    if (pipe(sd) == -1) {
        fprintf(stderr,"Pipe failed sd");
        return 1;
    }

    if (pipe(td) == -1) {
        fprintf(stderr,"Pipe failed sd");
        return 1;
    }

    printf("Enter a number: ");
    scanf("%s", write_msg);

    pid_child = fork();


    if (pid_child < 0) {
        fprintf(stderr, "Fork failed child");
        return 1;
    }

    if(pid_child > 0){ // parent

        //pass data to child

        close(fd[READ_END]);
        write(fd[WRITE_END], write_msg, strlen(write_msg)+1);
        close(fd[WRITE_END]);


        wait(NULL);

        close(td[WRITE_END]);
        read(td[READ_END], read_msg_parent, strlen(read_msg_parent)+1);
        printf("final output is: %s\n", read_msg_parent);
        fflush(stdout);
        close(td[READ_END]);


        kill(pid_child);
        printf("killed child with pid: %d\n" , pid_child);

        kill(pid_grandc);
        printf("killed grandchild with pid: %d\n" , pid_grandc);

    } else { // child + grandchild

        pid_grandc = fork();


        if (pid_grandc < 0) {
            fprintf(stderr, "Fork failed grand child");
            return 1;
        }

        if(pid_grandc > 0){ // child

            // get data from parent

            close(fd[WRITE_END]);
            read(fd[READ_END], read_msg_child, BUFFER_SIZE);
            sscanf(read_msg_child, "%d", &x);
            printf("Child: input %d and output %d\n", x, x*2);
            fflush(stdout);
            close(fd[READ_END]);



            // pass data to grandchild

            close(sd[READ_END]);
            x *= 2;
            sprintf(write_msg2, "%d", x);
            write(sd[WRITE_END], write_msg2, strlen(write_msg2)+1);
            close(sd[WRITE_END]);

            wait(NULL);
            exit(0);

        } else { // grandchild

            // get data from child

            close(sd[WRITE_END]);
            read(sd[READ_END], read_msg_grandchild, strlen(read_msg_grandchild)+1);
            close(sd[READ_END]);

            sscanf(read_msg_grandchild, "%d", &z);
            printf("Grandchild: input %d, output: %d\n",z, z*2);
            fflush(stdout);
            z *= 2;

            // pass data to child back
            close(td[READ_END]);
            sprintf(write_msg3, "%d",z);
            write(td[WRITE_END], write_msg3, strlen(write_msg3) + 1);
            close(td[WRITE_END]);

            exit(0);

        }

    }
    return 0;
}

И пример вывода:

> Enter a number: 12 
> Child: input 12 and output 24 
> Grandchild: input 24,output: 48 
> final output is: 48 
> killed child with pid: 7321 
> killed grandchild with pid: 1

1 Ответ

1 голос
/ 16 февраля 2020

В вашем коде, поскольку дочерний процесс создает процесс внука, родитель не знает pid внука.

Я думаю, что вы можете передать pid внука, используя дополнительный канал.

после проверки:

    if(pid_grandc > 0){ // child
    passGrandchildPid(newpipename, pid_grandc);  // function to write pid to pipe

    }
    // ...


void passGrandchildPid(int newpipename[2], int pid_grandc){
        int pid = grand_child_pid;
         close(newpipename[0]);          /* Close unused read end */
             write(newpipename[1], &pid , sizeof(pid));
             close(newpipename[1]);
             fflush(stdout);
    }

Затем в родительском процессе вы можете прочитать идентификатор процесса внука из этого нового канала и уничтожить его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...