我退出时为什么我的守护程序不会终止?

时间:2021-12-26 20:20:53

I'm reading about Linux process groups and sessions. From this site I see:

我正在阅读Linux进程组和会话。从这个网站我看到:

When a user logs out of a system, the kernel needs to terminate all the processes the user had running...To simplify this task, processes are organized into sets of sessions. The session's ID is the same as the pid of the process that created the session through the setsid() system call. That process is known as the session leader for that session group. All of that process's descendants are then members of that session unless they specifically remove themselves from it. The setsid() function does not take any arguments and returns the new session ID.

当用户退出系统时,内核需要终止用户运行的所有进程...为了简化此任务,将进程组织为多组会话。会话的ID与通过setsid()系统调用创建会话的进程的pid相同。该过程称为该会话组的会话负责人。所有该进程的后代都是该会话的成员,除非他们明确地将其自身移除。 setsid()函数不接受任何参数并返回新的会话ID。

What the article doesn't say is when the OS decides to terminate a user's sessions. My initial assumption was that when someone logs into a TTY, the TTY is the session leader and all processes invoked in that session belong to it unless they call setsid(). However, this is clearly wrong as verified by the simplest of examples. Consider this "daemon"... (I know it's not a real daemon, but it does fork)...

文章没有说的是OS何时决定终止用户的会话。我最初的假设是,当有人登录TTY时,TTY是会话负责人,并且该会话中调用的所有进程都属于它,除非他们调用setsid()。然而,正如最简单的例子所证实的那样,这显然是错误的。考虑一下这个“守护进程”......(我知道它不是一个真正的守护进程,但它会分叉)...

#include 
#include 
#include 
#include 

int main(void) {

  pid_t pid = fork();

  if(pid < 0) {
    perror("fork");
    exit(EXIT_FAILURE);
  }

  if(pid == 0) {
    FILE * heartbeat_file = fopen("daemon.out", "w");
    int hb = 0;
    while(1) {
      fprintf(heartbeat_file, "%d\n", hb);
      fflush(heartbeat_file);
      hb++;
      sleep(1);
    }
  } 
  exit(EXIT_SUCCESS);
}

From the code, we see that the child continually writes to a file, and the parent exits. Note that I'm never calling setsid().

从代码中,我们看到孩子不断写入文件,父母退出。请注意,我从不调用setsid()。

If I log in, run the daemon, and then log out, and then log in, the daemon is still running! I can remove the call to fork() and as expected, the process terminates when I log out. Can anyone explain why fork causes the app not to exit when I log out?

如果我登录,运行守护程序,然后注销,然后登录,守护程序仍在运行!我可以删除对fork()的调用,并且正如预期的那样,该过程在我注销时终止。任何人都可以解释为什么在我退出时fork导致应用程序不退出?

1 个解决方案

#1


1  

When you fork while letting the parent exit, you create an orphan process (http://en.wikipedia.org/wiki/Orphan_process). Such orphans are re-parented to the init process. I would assume from what you observe that the re-parenting modifies the session's ID.

当你让父进程退出时,你创建一个孤儿进程(http://en.wikipedia.org/wiki/Orphan_process)。这些孤儿被重新作为初始化过程的父级。我会假设从你观察到的重新父母修改会话的ID。

A straightforward way to test this assumption would be for the parent to wait on the child (sorry i'm not on my linux box at the moment, and can't do it).

测试这个假设的直接方法是让父母等待孩子(对不起,我现在不在我的linux盒子上,而且不能这样做)。

#1


1  

When you fork while letting the parent exit, you create an orphan process (http://en.wikipedia.org/wiki/Orphan_process). Such orphans are re-parented to the init process. I would assume from what you observe that the re-parenting modifies the session's ID.

当你让父进程退出时,你创建一个孤儿进程(http://en.wikipedia.org/wiki/Orphan_process)。这些孤儿被重新作为初始化过程的父级。我会假设从你观察到的重新父母修改会话的ID。

A straightforward way to test this assumption would be for the parent to wait on the child (sorry i'm not on my linux box at the moment, and can't do it).

测试这个假设的直接方法是让父母等待孩子(对不起,我现在不在我的linux盒子上,而且不能这样做)。