为什么我fork的进程将systemd作为父进程?

时间:2016-11-04 13:34:34

标签: 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 }

有时它工作正常,结果如下:

./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

有人能帮助我直截了当吗?

3 个答案:

答案 0 :(得分:4)

我认为,有时会发生种族情况,父母会在孩子面前死亡。因此,孩子从初始过程成为孩子。在你的情况下,那必须是systemd。

无论如何,请注意,运行fork(); fork();将产生4个进程,这可能(可能)不是您想要的。像对第一个一样使用控制结构来控制程序的行为。

答案 1 :(得分:4)

&#34;不一致&#34;您观察到的是因为有时父进程在子进程终止之前已退出。因此,这些子进程变为"orphans" 父流程对他们来说不是waiting。结果,他们重新成为了父母。到init进程。 传统上,&#34; init&#34;过程是1,它并不总是正确的。 POSIX将其保留为实现定义的

  

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

因此,您会看到一个特定的PID作为父级(在您的示例中为1599),恰好是&#34; init&#34;在Linux上等效的进程。 systemd是Debian Linux发行版中使用的init变体 - 它遵循稍微复杂的实现。

在本质上,你观察到的是很正常的。理想情况下,您应收割所有流程,以避免zombie processes

答案 2 :(得分:1)

这是因为父进程首先终止。 在Linux中没有ophan进程。它们被分配到init进程。

如果要控制进程以使子进程首先终止,请使父进程等待。使用wait() sys_call。

Example:

   #include <stdio.h>
   #include <stdlib.h>
   #include <unistd.h>
   int main(void)
   {
        int pid;
        int pid2;
        pid = fork();
        if(pid < 0){
                 exit(1);
        }
        if(pid == 0){ // child process
            pid2 = fork()
            if (pid2 < 0)
                exit(1);
            if (pid2 == 0)
            {
                printf("pid:%dppid:%d\n",getpid(),getppid());
                exit(0);
            }
            wait();
            printf("pid:%d ppid:%d\n",getpid(),getppid());
            exit(0);
        }
        else{         // parent process
           wait();
           printf("parent pid:%d ppid:%d\n",getpid(),getppid());
           exit(0);
        }       
        return 0;            
  }
  

systemd是Linux发行版中用于引导的init系统   用户空间并随后管理所有流程