fork调用后父进程id不一致?

时间:2017-12-20 00:21:03

标签: c unix process operating-system

我正在创建一个小进程树和打印进程id,父进程id, 进程组ID和进程会话标识

            A(g1,s1) 

           / \

  (g1,s1)B     C (g2,s1)

(g,s):(进程组ID,进程会话ID)

问题:在process C中,output of parent process id更改,它应显示ppid作为进程A的pid但不是。另外something it prints the correct output.为何选择inconsistency in the output

代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


int main(int argc, char **argv) {
    int err= EXIT_SUCCESS;
    pid_t process_id_A;
    pid_t process_id_B;
    pid_t process_id_C;

    /* Currently process A */
    process_id_A = getpid();
    printf("Process A: pid: %ld ppid: %ld gid: %ld sid: %ld \n",(long)getpid(),(long)getppid(),(long)getpgrp(),(long)getsid(0));

    /* Create process B */
    process_id_B= fork();
    switch(process_id_B)
    {
    case 0:
        /* Inside process B */
        //do nothing , ie same process group id and session id as process A
        printf("Process B: pid: %ld ppid: %ld gid: %ld sid: %ld \n",(long)getpid(),(long)getppid(),(long)getpgrp(),(long)getsid(0));
        break;
    default:
        break;
    }

    /* Create process C */
    //check if process is A , then create process C as child of A
    if(getpid() == process_id_A)
    {
        process_id_C = fork();
        switch(process_id_C)
        {
        case 0:
            /* Inside process C */

            /* Change process group id */
            err = setpgid(0,0);
            if(err == -1)
            {
                perror("setpgid() error");
                goto exit;
            }
            printf("Process C: pid: %ld ppid: %ld gid: %ld sid: %ld \n",(long)getpid(),(long)getppid(),(long)getpgrp(),(long)getsid(0));
            break;
        default:
            break;
        }
    }

    exit:
        return err;
}

输出:

$ ./setpgid_demo.o  (1st run: correct output)
Process A: pid: 14224 ppid: 13562 gid: 14224 sid: 13562
Process B: pid: 14225 ppid: 14224 gid: 14224 sid: 13562 
Process C: pid: 14226 ppid: 14224 gid: 14226 sid: 13562 

$ ./setpgid_demo.o  (2nd run : Incorrect output)
Process A: pid: 14227 ppid: 13562 gid: 14227 sid: 13562 
Process B: pid: 14228 ppid: 14227 gid: 14227 sid: 13562 
Process C: pid: 14229 ppid: 3221 gid: 14229 sid: 13562

1 个答案:

答案 0 :(得分:3)

我接受了你的代码并且只用int main(int argc, char **argv)替换int main(void)(因为我的默认编译选项抱怨未使用的变量并停止代码编译),然后它干净地编译(做得好;我通常必须做更多的工作,让代码为我干净利地编译)。并且,当我运行它(它被称为pgid37)时,我得到了结果:

$ ./pgid37
Process A: pid: 27489 ppid: 742 gid: 27489 sid: 740 
Process B: pid: 27490 ppid: 27489 gid: 27489 sid: 740 
Process C: pid: 27491 ppid: 1 gid: 27491 sid: 740 
$

请注意,C的父PID(PPID)为1,而不是27489.由于A进程不等待B或C退出,这对我来说并不奇怪。

  • 我不会对你曾经看过的3321的PPID有一个好的(甚至是坏的)解释。

以下是您的代码的修改版本,其中父级等待子级 - 源代码位于pgid11.c,程序名为pgid11

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

static void report_ids(const char *tag)
{
    printf("Process %s: pid: %ld ppid: %ld gid: %ld sid: %ld \n",
           tag, (long)getpid(), (long)getppid(), (long)getpgrp(), (long)getsid(0));
}

int main(void)
{
    /* Currently process A */
    report_ids("A");

    /* Create process B */
    pid_t process_id_B = fork();
    if (process_id_B == 0)
    {
        report_ids("B");
        return EXIT_SUCCESS;
    }

    pid_t process_id_C = fork();
    if (process_id_C == 0)
    {
        /* Change process group id */
        if (setpgid(0, 0) == -1)
        {
            perror("setpgid() error");
            return EXIT_FAILURE;
        }
        report_ids("C");
        return EXIT_SUCCESS;
    }

    int corpse;
    int status;
    while ((corpse = wait(&status)) > 0)
    {
        printf("%d: PID %d exited with status 0x%.4X\n",
               (int)getpid(), corpse, status);
    }

    return 0;
}

一次试运行给了我:

$ ./pgid11
Process A: pid: 27527 ppid: 742 gid: 27527 sid: 740 
Process B: pid: 27528 ppid: 27527 gid: 27527 sid: 740 
27527: PID 27528 exited with status 0x0000
Process C: pid: 27529 ppid: 27527 gid: 27529 sid: 740 
27527: PID 27529 exited with status 0x0000
$

这一次,两个孩子都报告PPID等于第一个过程27527,这非常符合预期。