2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 父进程中getpid()值与子进程中getppid()值不相同的问题及解释

父进程中getpid()值与子进程中getppid()值不相同的问题及解释

时间:2024-03-25 04:03:21

相关推荐

父进程中getpid()值与子进程中getppid()值不相同的问题及解释

父进程中getpid()值与子进程中getppid()值不相同的问题及解释

使用fork()创建一个新的子进程,并调用getpid()getppid()查看父子进程之间的pid的关系。示例代码如下:

#include "common.h"int main() {pid_t pid;if ( (pid = fork()) < 0 ) {perror("fork()");exit(1);}if ( pid ) {printf("parent process <%d>--><%d>--><%d>\n", getppid(), getpid(), pid);} else {printf("child process <%d>--><%d>\n", getppid(), getpid());}return 0;}

输出结果为:

parent process <>--><11595>--><11596>child process <1387>--><11596>

按照父子进程之间的关系,应该有这样的结论:子进程的父进程pid应该等于实际父进程的pid,即在子进程中调用getppid()得到的值应该和父进程中调用getpid()得到的值相同。

此时输出结果中,父进程中查到子进程的pid = 11596,这和子进程中的11596值相同,是没问题的,但子进程中ppid不是11595而是1387,这是为什么呢?

使用ps命令查看系统中的进程,可以看到1387对应的是systemd

ubuntu@ubuntu:~/Desktop/linux$ ps -ePID TTYTIME CMD1387 ? 00:00:00 systemdubuntu@ubuntu:~/Desktop/linux$ ps -e | grep "systemd"1 ? 00:00:03 systemd1054 ? 00:00:00 systemd1387 ? 00:00:00 systemd

先来了解一下什么是systemd

Linux 操作系统的启动首先从 BIOS 开始,然后由 Boot Loader 载入内核,并初始化内核。内核初始化的最后一步就是启动 init 进程。这个进程是系统的第一个进程,PID 为 1,又叫超级进程,也叫根进程。它负责产生其他所有用户进程。所有的进程都会被挂在这个进程下,如果这个进程退出了,那么所有的进程都被 kill 。如果一个子进程的父进程退了,那么这个子进程会被挂到 PID 1 下面。

历史上,Linux 的启动一直采用 init 进程,这种方法有两个缺点。一是启动时间长。init 进程是串行启动,只有前一个进程启动完,才会启动下一个进程。二是启动脚本复杂。init 进程只是执行启动脚本,不管其他事情。脚本需要自己处理各种情况,这往往使得脚本变得很长。

Systemd 就是为了解决这些问题而诞生的。它的设计目标是,为系统的启动和管理提供一套完整的解决方案。根据 Linux 惯例,字母d是守护进程(daemon)的缩写。Systemd 这个名字的含义,就是它要守护整个系统。使用了 Systemd,就不需要再用 init了。Systemd 取代了 initd,成为系统的第一个进程(PID 等于 1),其他进程都是它的子进程。

综上所述,因为测试代码执行的环境中只有一个CPU,所以子进程要等待父进程执行结束后才能执行(示例代码父进程的任务可以在一个时间片内执行完,否则在下次调度时父子进程调度顺序不确定),而父进程结束执行后,子进程会变为僵尸进程挂在systemd下。如果执行环境中存在多个CPU,运行相同的代码,会看到不一样的结果,父进程中getpid()值与子进程中getppid()值会出现相同的情况。

问题遗留:为什么子进程中的systemdpid不是1,使用ps查看时为什么有多个systemd进程?

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。