【问题标题】:Grandchild process has PID 1 in C孙子进程在 C 中具有 PID 1
【发布时间】:2020-02-08 18:40:38
【问题描述】:

我正在尝试使用管道将输入从父级传递给子级,然后从子级传递给孙子级。之后,孙子将结果发送回父进程,父进程将终止这两个进程。

我可以使用管道进行数据传递,但我想我不能杀死进程,因为孙子的 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

【问题讨论】:

  • 很多关于代码结构的事情对我来说很奇怪,但主要问题似乎是你在初始化之前杀死了pid_grandc
  • 我是 C 编程新手,但我认为 wait(NULL) 可以处理它。
  • 何时准确初始化,如何修复?
  • 我不明白。 pid_grandc 是如何声明的?您是否认为它应该具有任何有意义的价值?它看起来未初始化 - 您不会在任何地方分配给 pid_grandc
  • 您从未在父级中设置 pid_grandc。您将其设置在子级中,但这对父级没有影响。要在父级中获取孙子的 pid,您需要以某种方式将其从子级发送给父级...

标签: c process


【解决方案1】:

在您的代码中,由于子进程是创建孙子进程的那个,因此父进程不知道孙子进程的 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);
    }

然后在父进程中,您可以从这个新管道中读取孙子进程的 ID 并将其杀死。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    • 2023-04-04
    • 2014-04-01
    • 2019-01-09
    相关资源
    最近更新 更多