Luc*_*cas 5 c linux fork systemd
我正在Linux中学习fork(),这是我的程序:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 int main(void){
5 int pid;
6 pid = fork();
7 if(pid < 0){
8 exit(1);
9 }
10 if(pid == 0){
11 fork();
12 fork();
13 printf("pid:%d ppid:%d\n",getpid(),getppid());
14 exit(0);
15 }
16 else{
17 printf("parent pid:%d ppid:%d\n",getpid(),getppid());
18 exit(0);
19 }
20
21 }
Run Code Online (Sandbox Code Playgroud)
有时效果很好,结果如下:
./test1.out
parent pid:27596 ppid:21425
pid:27599 ppid:27597
pid:27597 ppid:27596
pid:27598 ppid:27597
pid:27600 ppid:27598
Run Code Online (Sandbox Code Playgroud)
但是结果并不一致,通常是这样的:
parent pid:27566 ppid:21425
pid:27567 ppid:27566
pid:27568 ppid:27567
pid:27569 ppid:1599
pid:27570 ppid:1599
Run Code Online (Sandbox Code Playgroud)
这对我来说没有任何意义,所以我输入了$ ps aux以找出1599的处理过程:(删除了一些列)
USER PID VSZ RSS STAT START COMMAND
linux 1599 63236 6316 Ss 09:03 /lib/systemd/systemd --user
Run Code Online (Sandbox Code Playgroud)
有人可以帮我整理一下吗?
您观察到的“不一致”是因为有时父进程在其子进程终止之前就退出了。因此,这些子进程成为“孤儿”,因为其父进程不在等待它们。结果,它们被“重新父”到了初始化过程。传统上,“ init”进程的进程ID为1,但并不总是如此。POSIX将其保留为实现定义的内容:
调用进程的所有现有子进程和僵尸进程的父进程ID必须设置为实现定义的系统进程的进程ID。即,这些过程应由特殊的系统过程继承。
因此,您会看到一个特定的PID作为父对象(在您的示例中为1599),在您的Linux上恰好相当于“初始化”进程。该systemd是Debian的Linux发行版使用的初始化变种-它遵循一个稍微复杂的实现。
本质上,您观察到的是很正常的。理想情况下,您应该收获所有进程以避免僵尸进程。
我想,有时,会发生竞争条件,父母先于孩子去世。因此,子进程成为 init 进程的子进程。就你而言,这必须是 systemd。
无论如何,请注意,运行fork(); fork();将产生 4 个进程,这(可能)不是您想要的。像使用第一个结构一样使用控制结构来对程序的行为进行精细控制。