为什么我派生的进程将systemd作为其父级? [英] Why do processes I fork get systemd as their parent?

查看:324
本文介绍了为什么我派生的进程将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 }

有时效果很好,结果如下:

./test1.out
parent pid:27596 ppid:21425
pid:27599 ppid:27597
pid:27597 ppid:27596
pid:27598 ppid:27597
pid:27600 ppid:27598

但是结果并不总是一致的,通常是这样的:

parent pid:27566 ppid:21425
pid:27567 ppid:27566
pid:27568 ppid:27567
pid:27569 ppid:1599
pid:27570 ppid:1599

这对我来说毫无意义,所以我输入了 $ ps aux 来找出1599的处理过程:(删除了一些列)

  USER       PID  VSZ   RSS    STAT START   COMMAND
  linux     1599  63236  6316   Ss   09:03  /lib/systemd/systemd --user

有人可以帮我把事情弄清楚吗?

解决方案

您观察到的不一致"是因为有时父进程在子进程终止之前退出了.因此,这些子进程成为孤立的" 作为其子进程 父进程不是 正在等待 他们.结果,它们被重新父"到了初始化过程. 传统上,"init"进程的进程ID为1,但并不总是如此. POSIX 将其保留为实现定义:

所有现有子进程的父进程ID,以及 调用进程的僵尸进程应设置为进程ID 实现定义的系统过程的过程.也就是说,这些过程 应该由特殊的系统进程继承.

因此,您将特定的PID视为父对象(在您的示例中为1599),在您的Linux上恰好相当于"init"进程. systemd 是Debian Linux发行版中使用的init变体-实现起来稍微复杂一些. /p>

从本质上讲,您观察到的是很正常的.理想情况下,您应该获取所有进程,以避免僵尸进程

I am learning fork() in Linux, and here is my program:

  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 }

Sometimes it worked fine, with result like this:

./test1.out
parent pid:27596 ppid:21425
pid:27599 ppid:27597
pid:27597 ppid:27596
pid:27598 ppid:27597
pid:27600 ppid:27598

But the result was not consistent, more often than not it worked like this:

parent pid:27566 ppid:21425
pid:27567 ppid:27566
pid:27568 ppid:27567
pid:27569 ppid:1599
pid:27570 ppid:1599

Which makes no sense to me, so I typed $ps aux to find out what process 1599 is:(with some columns deleted)

  USER       PID  VSZ   RSS    STAT START   COMMAND
  linux     1599  63236  6316   Ss   09:03  /lib/systemd/systemd --user

Can anybody help me straighted things up?

解决方案

The "inconsistency" you observed is because sometimes, the parent process(es) exited before their child process(es) terminated. So, these child processes become "orphans" as their parent processes are not waiting for them. As a result, they are "re-parented" to the init process. While traditionally the process id of the "init" process is 1, it's not always true. POSIX leaves it as implementation-defined:

The parent process ID of all of the existing child processes and zombie processes of the calling process shall be set to the process ID of an implementation-defined system process. That is, these processes shall be inherited by a special system process.

Thus you see a particular PID as the parent (1599 in your example), which happens to be "init" process equivalent on your Linux. The systemd is an init variant used in Debian Linux distributions - which follows a slightly more complicated implementation.

In essense, what you observed is pretty normal. Ideally, you should reap all the processes in order to avoid zombie processes.

这篇关于为什么我派生的进程将systemd作为其父级?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆