为什么在编写linux守护进程时必须从tty分离?

当我试图写在linux下使用C的守护进程时,我被告知我应该在fork代码块后添加以下代码:

/* Preparations */ ... /* Fork a new process */ pid_t cpid = fork(); if (cpid == -1){perror("fork");exit(1);} if (cpid > 0){exit(0);} /* WHY detach from tty ? */ int fd = open("/dev/tty", O_RDWR); ioctl(fd, TIOCNOTTY, NULL); /* Why set PGID as current PID ? */ setpgid(getpid(), 0); 

我的问题是:是否有必要做以上的操作?

Solutions Collecting From Web of "为什么在编写linux守护进程时必须从tty分离?"

您必须取消终端进程与终端的关联,以避免发送与终端操作相关的信号(例如终端会话结束时的SIGHUP以及潜在的SIGTTIN和SIGTTOU)。

但是请注意,使用TIOCNOTTY ioctl从终端分离的方式在很大程度上已经过时。 你应该使用setsid()来代替。

守护进程离开其原始进程组的原因是不接收发送到该组的信号。 请注意setsid()也将您的进程放置在它自己的进程组中。

另一个答案是清楚的,在技术上是正确的(所以我相应地upvoted)。

另一个答案是: “不,不要编写守护自己的代码。”

而是使用一个流程监督框架(如daemontools或runit或launchd )来为您处理这个问题。

传统的UNIX服务器是自我守护的,因此在当前的工作目录,进程组和会话独立性,信号掩码和配置,文件系统根目录,权限,umask,打开的文件描述符等方面都是如此。

但是,这些进程属性的大部分或全部都是通过exec()继承的,这意味着服务器进程通常可以通过所需的进程组,工作目录,根等“出生”。自己几乎不需要做任何事情,尽管您通常仍然必须自己管理特权操作和特权撤销。

(事实上​​,我认为编写自我后台程序存在着长期的风险,因为程序员会花费时间在辅助代码上而不是程序的主要目的上,从而复制和粘贴“后台”程序。 )