守护进程时是否需要更改父进程?

我正在阅读有关守护程序的守则https://en.wikipedia.org/wiki/Daemon_%28computing%29#Creation

在严格的技术意义上,类Unix系统进程是一个守护进程,当其父进程终止并且守护进程被分配了init进程(进程号1)作为其父进程并且没有控制terminal时。 但是更常见的是,守护进程可能是任何后台进程,无论是否是init进程的subprocess。

在类Unix系统上,当进程从命令行或启动脚本(如初始化脚本或SystemStarter脚本)启动时,进程成为守护程序的常用方法包括:

  1. 从控制tty分离
  2. 成为会议的领导者
  3. 成为一个过程组长
  4. 通过分叉和退出(一次或两次)执行后台任务。 这个过程有时需要成为会议的领导者。 它也允许父进程继续正常执行。
  5. 将根目录(/)设置为当前工作目录,以便进程不保留可能位于已装入文件系统上的任何正在使用的目录(使其可以被卸载)。
  6. 将umask更改为0以允许open(),creat()和其他操作系统调用提供其自己的权限掩码,而不依赖调用者的umask
  7. 在执行时closures父进程保持打开的所有inheritance文件,包括标准stream(stdin,stdout和stderr)的文件描述符0,1和2。 所需的文件将在稍后打开。
  8. 使用日志文件,控制台或/ dev / null作为stdin,stdout和stderr

如果进程是由超级服务器守护进程(如inetd,launchd或systemd)启动的,则超级服务器守护进程将为进程执行这些function[5] [6] [7](除了旧式的守护进程转换为在systemd下运行,并在inetd [5]下指定为Type = forking [7]和“multi-threaded”数据报服务器)。

  1. 是否有一步改变进程的父进程被守护进程? 在我看来,没有任何步骤呢?

    守护进程时是否需要更改父进程?

  2. 在改变一个进程的父进程( 一个进程不一定被守护进程)之后 ,该进程是否可以关联到新的父进程的控制tty? (问题的目的是看“保持一个与新父过程的控制过程无关的过程”是否是“改变过程的父过程”的必要条件。)

看到我的相关问题https://unix.stackexchange.com/questions/266565/daemonize-a-process-in-shell

谢谢。

Unix进程的父进程不能被进程本身改变。 创建一个守护进程的典型方法涉及到一个fork调用(它创建了将成为守护进程的进程)。 然后初始化进程退出,新的孤儿子进程将被init进程继承,成为新的父进程。 这是在步骤4中处理的init唯一会做的就是等待所有的孩子退出。 init没有控制TTY,所以一旦被init继承,守护进程就不能再与控制TTY关联了。 解除关联的主要原因是为了防止从TTY(hangup和control-C等)生成的信号到达守护进程。

守护进程通常有两种运行方式:

  1. 从一个shell脚本。 脚本运行守护进程的可执行文件,并在命令结束时使用&运算符将守护进程置于后台,可能使用I / O重定向来设置守护进程的stdin,stdout和/或stderr,然后退出而不保留守护进程家长。 从shell运行一个可执行文件涉及shell执行一个fork然后在要运行的可执行文件的子进程中执行一个exec

  2. 守护程序有一个选项来守护自己。 当用这个选项运行时,它会在子进程中执行一个fork然后由一个具有适当参数集的exec自身exec 。 父母通常会在fork后退出,因为被要求做的工作已经完成。 如果没有,子进程需要一个额外的fork来给它一个可以退出的父进程。 注意:这就是为什么很多通常作为守护进程运行的程序可以在不成为守护进程的情况下直接运行的原因,“成为守护进程”选项将导致子进程关闭stdin / stdout / stderr,然后只exec它自己的可执行文件而不执行“成为守护进程“的选择。

我会建议使用守护进程(3) 。 另见证书(7)

你的列表没有明确提到setsid(2) 。

MUSL libc有一个legacy / daemon.c ,它分叉两次并执行setsid