为什么我的分叉进程的父pid与父进程的pid不同?

时间:2018-01-23 09:57:43

标签: c fork pid unistd.h

我试图理解一些unistd.h函数是如何工作的。 这是我写的代码:

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

int main(){
  pid_t pid;
  pid=fork();
  switch(pid) {
  case 0: //child
     printf("case 0:\nchild %d\nparent %d\n", getpid(), getppid());
     break;
  default: //parent
     printf("default:\npid(child) %d\nparent %d\n", pid, getpid());
     break;
  }
}

我认为getppid()case 0获得的父pid和getpid()案例中default获得的父pid应该是相同的,但是这是我的小程序的输出:

default:
pid(child) 29208
parent 29207

Process returned 0 (0x0)   execution time : 0.001s
Press ENTER to continue.
case 0:
child 29208
parent 1017

为什么他们不一样? (案件中为29207,另一案件中为1017)

2 个答案:

答案 0 :(得分:3)

你应该减慢执行速度。如您所见,终端子项在父项完成后执行。在这种情况下,它变成一个孤儿,它的PID被重新分配给不同的进程。我不知道这在Linux上是否有效,但在我的Mac上它被重新分配到进程1.因此在每个之前添加sleep() printf()。< / p>

修改

我已编译(使用llvm-gcc编译)并在添加睡眠之前运行您的代码:

 $  ./test
default:
pid(child) 2688
parent 2687
case 0:
child 2688
parent 1

之后:

 $  ./test 
default:
pid(child) 2780
parent 2779
case 0:
child 2780
parent 2779

<强> EDIT2

由于将sleep()放在孩子的PID中解决了什么,我改变了关于应该放置它的位置的建议。

<强> EDIT3

由于我的回答是被接受而不是Toby的更好,所以值得一提的是,正确的同步机制将使用wait()函数。

答案 1 :(得分:2)

如果父母没有为孩子wait(),则可能会在孩子致电getppid()之前退出。如果您希望父级仍然存在并且是父级,则可以通过使其等待来确保:

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

int main()
{
    const pid_t pid = fork();
    switch (pid) {
    case 0:
        printf("in child: me: %d; parent %d\n", getpid(), getppid());
        break;
    default: //parent
        printf("in parent: child: %d; me %d\n", pid, getpid());
        wait(NULL);
        break;
    }
}

(为方便起见,我还添加了您忘记包含的标题 - 这表示您的编辑中没有启用足够的警告。)