本文链接:http://blog.csdn.net/lyh__521/article/details/50148025
孙子进程的父进程是谁?
为了方便描述,这里将子进程中创建的子进程称为孙子进程。
测试代码:
/*
* getpid() 获取当前进程PID
* getppid() 获取父进程的PID
*/
#include<stdio.h>
#include<stdlib.h>
main()
{
int pid1,pid2;
pid1 = fork(); //创建子进程
switch(pid1)
{
case -1:
printf("create pid1 error!\n");
break;
case 0:
pid2 = fork(); //子进程中创建孙子进程
switch(pid2)
{
case -1:
printf("create pid2 error!\n");
break;
case 0:
sleep(2);
printf("孙子:pid = %d ppid = %d\n",getpid(),getppid());
break;
default:
printf("儿子:pid = %d ppid = %d pid2 = %d\n",getpid(),getppid(),pid2);
}
// exit(-1); //使孙子进程变为孤儿进程
break;
default:
printf("父亲:pid = %d pid1 = %d\n",getpid(),pid1);
}
sleep(20); //不让进程退出
}
运行结果:
pid 是当前进程ID,ppid 是父进程ID
显示孙子进程的 ppid 和儿子进程的PID是一样的,即他的父进程就是儿子进程。
再看一下进程树:在另一终端执行命令 pstree lyh #lyh是我的用户名
a.out–a.out–a.out 可以看到与程序的输出是吻合的,所以进程的父进程就是直接fork出他的进程。
孤儿进程被谁收养?
修改上面的代码让儿子进程先退出,孙子进程变为孤儿进程。
/*
* getpid() 获取当前进程PID
* getppid() 获取父进程的PID
*/
#include<stdio.h>
#include<stdlib.h>
main()
{
int pid1,pid2;
pid1 = fork(); //创建子进程
switch(pid1)
{
case -1:
printf("create pid1 error!\n");
break;
case 0:
pid2 = fork(); //子进程中创建孙子进程
switch(pid2)
{
case -1:
printf("create pid2 error!\n");
break;
case 0:
sleep(2);
printf("孙子:pid = %d ppid = %d\n",getpid(),getppid());
break;
default:
printf("儿子:pid = %d ppid = %d pid2 = %d\n",getpid(),getppid(),pid2);
}
exit(-1); //使孙子进程变为孤儿进程
break;
default:
printf("父亲:pid = %d pid1 = %d\n",getpid(),pid1);
}
sleep(20); //不让进程退出
}
运行:
好像有点奇怪的地方。书上说孤儿进程被 1号进程init 收养,但是这里为什么孤儿进程被2197进程收养了呢?重复执行几次都是这个结果,每次都是2197,并不是书上说的 1 。看来2197也是个特殊的进程。
我们用 ps 查看一下这个进程:
它对应的/sbin/upstart ,这是个什么鬼?
于是求助度娘得到答案:原来 upstart 是init 演进来的,可以说是一种新型的 init系统,传统的 sysvinit 已经淡出历史舞台,新系统 UpStart 和 systemd 各有特点,而越来越多的 Linux 发行版采纳了 systemd。
ubuntu 较新的发行版都用 upstart 代替 init 来收养孤儿进程。
详细资料请看:http://www.ibm.com/developerworks/cn/linux/1407_liuming_init2/
不同的系统上,upstart 的pid不一定是2197。
下面是我在CentOS7上运行的结果
如我们所愿,孤儿进程被我们熟悉的 init 进程收养了。