DAEMON(3) 如何工作?作为后台进程运行

DAEMON(3) 如何工作?作为后台进程运行

使进程与终端分离的步骤是什么?为此我找到了手册页daemon()在描述中,他们提到

如果 nochdir 为零,则 daemon() 将进程的当前工作目录更改为根目录(“/”);否则,当前工作目录保持不变。

如果 noclose 为零,则 daemon() 将标准输入、标准输出和标准错误重定向到 /dev/null;否则,不会对这些文件描述符进行任何更改。

实际上,我试图让我的 python 代码作为守护进程运行。我找到了tcollector代码这里。在该代码中,他们也遵循与 的描述中相同的步骤daemon()。所以我的问题是,我们为什么要执行这些步骤(wrtdaemonize()tcollector)像

为什么更改dir/umaskto022然后调用os.setsid()等等。

答案1

实际上比您引用的内容更多,但我认为手册页可能更清晰。

如果 nochdir 为零,daemon()则将进程的当前工作目录更改为根目录 ( /)

这里的假设是该程序是从管理员命令行启动的,其想法是将守护进程与管理员当时正在执行的操作分离。更改工作目录以/防止守护程序使安装点保持繁忙。例如,如果工作目录是/home/admin,一段时间后您想卸载/home,守护进程会阻止这种情况。

如果 noclose 为零,daemon()则将标准输入、标准输出和标准错误重定向到/dev/null;

这是为了防止守护进程通过向终端写入杂散错误消息等来迷惑用户。守护进程可能应该做的是打开一些(配置的)日志文件,并在那里写入它想要与外部通信的任何内容。

(此函数分叉,如果 fork(2) 成功,则父级调用 _exit(2),以便只有子级才能看到更多错误。)

再次强调,要与 admins shell 会话解除关联,主程序会立即返回,而其他部分则留在后台,因此无需显式要求程序在后台启动(例如./daemon &

现在,手册页没有明确说明,但在这里暗示(在错误下):

该函数的 GNU C 库实现取自 BSD,并且不采用确保生成的守护进程所必需的双叉技术(即 fork(2)、setsid(2)、fork(2))。不是会话负责人。相反,生成的守护进程是会话领导者。

daemon()还打电话setsid()从会话中释放自己控制终端,因此来自终端发送的信号。但正如引用所述,这留下了一种可能性:如果它打开一个终端设备,它可能会意外地将其作为控制终端。为了避免这种情况,一些程序从子进程中调用,fork()然后setsid()再次 fork ,退出两个父进程,这样生成的进程就不是会话领导者(中间的进程是/曾经是),并且无法获得控制终端。你提到的Python程序正是这样做的。

更改umask似乎与守护进程无关。也许该程序对此有特殊的需求。

相关内容