Linux 守护进程

Posted

技术标签:

【中文标题】Linux 守护进程【英文标题】:Linux daemonize 【发布时间】:2011-03-06 22:49:54 【问题描述】:

我正在编写一个 Linux 守护程序。我找到了两种方法。

    通过调用fork() 并设置sid 来守护进程。 使用& 运行您的程序。

哪种方法是正确的?

【问题讨论】:

你可以使用 nohup:***.com/questions/958249/… 【参考方案1】:

来自http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC16

以下是成为守护进程的步骤:

    fork() 以便父级可以退出,这会将控制权返回给调用程序的命令行或 shell。此步骤是必需的,以便保证新流程不是流程组负责人。如果您是流程组负责人,下一步 setid() 将失败。 setsid() 成为进程组和会话组组长。由于控制终端与会话相关联,而这个新会话尚未获得控制终端,我们的进程现在没有控制终端,这对守护进程来说是件好事。 fork() 再次让父级(会话组负责人)可以退出。这意味着我们作为非会话组长,永远无法重新获得控制终端。 chdir("/") 以确保我们的进程不会保留任何正在使用的目录。不这样做可能会导致管理员无法卸载文件系统,因为它是我们的当前目录。 [等效地,我们可以更改为包含对守护程序的操作很重要的文件的任何目录。] umask(0) 这样我们就可以完全控制我们编写的任何内容的权限。我们不知道我们可能继承了什么 umask。 [这一步是可选的] close() fds 0、1 和 2。这将释放我们从父进程继承的标准输入、输出和错误。我们无法知道这些 fd 可能被重定向到哪里。请注意,许多守护程序使用 sysconf() 来确定限制 _SC_OPEN_MAX。 _SC_OPEN_MAX 告诉您最大打开文件/进程。然后在一个循环中,守护进程可以关闭所有可能的文件描述符。您必须决定是否需要这样做。如果您认为可能有文件描述符打开,您应该关闭它们,因为并发文件描述符的数量是有限制的。 为标准输入、标准输出和标准错误建立新的开放描述符。即使您不打算使用它们,打开它们仍然是一个好主意。这些的精确处理是一个品味问题。例如,如果您有一个日志文件,您可能希望将其作为标准输出或标准错误打开,并将“/dev/null”作为标准输入打开;或者,您可以将“/dev/console”作为标准错误和/或标准输出打开,将“/dev/null”作为标准输入,或任何其他对您的特定守护进程有意义的组合。

更好的是,只需调用daemon() 函数(如果可用)。

【讨论】:

您必须关闭所有打开的描述符。否则,文件可能会继续具有引用,例如,这将防止它们被删除。这很像 chdir("/")。 @n-alexanderso - daemon() 是双叉吗? Ruby WEBrick daemonize 的一个很好的例子(切换源代码):ruby-doc.org/stdlib-2.1.1/libdoc/webrick/rdoc/WEBrick/… daemon() 在 Linux 上可能无法正常工作。来自 daemon() 手册页:“该函数的 GNU C 库实现取自 BSD,并且没有采用双叉技术(即 fork(2)、setsid(2)、fork(2))有必要确保生成的守护进程不是会话负责人。相反,生成的守护进程是会话负责人。"【参考方案2】:

我建议根本不要将您的程序编写为守护程序。使用给定的文件描述符、当前目录、进程组等使其在前台运行。

如果您想将该程序作为守护进程运行,请使用 start-stop-daemon(8)、init(8)、runsv(来自 runit)、upstart、systemd 或其他任何方式将您的进程作为守护进程启动。也就是说,让您的用户决定如何运行您的程序,而不是强制它必须作为守护程序运行。

【讨论】:

+1。至少,提供在前台运行的选项。 很抱歉带来一个旧答案,但是 monit 也可以将您的进程作为守护进程启动吗?【参考方案3】:

只需使用daemon(3)(来自unistd.h)。

daemon() 函数用于程序 想要脱离 控制终端并在 背景作为系统守护进程。 ...

【讨论】:

我花了几天时间研究如何使用 jenkins 在 ubuntu 上将烧瓶应用程序作为守护程序运行,直到我看到你的建议。谢谢!我的问题通过 shell 命令解决了 export BUILD_ID=dontKillMe daemon flask run【参考方案4】:

第一个。第二个不是守护进程,而是在后台运行。守护程序应该在自己的会话和进程组中,并且应该有控制终端。

【讨论】:

但我还是不明白设置自己的会话和进程组有什么用【参考方案5】:

实际上要创建一个守护进程,你必须双叉。

使用 & 运行程序会使 shell 在后台运行程序,这不会使其成为守护进程。守护进程有 init (pid 1) 作为父进程,这就是需要双叉的原因。

因此,如果您的程序是守护程序,那么做事的好方法是自己处理这个问题(还有更多方法,请参阅here)。您也可以使用 start-stop-daemon 程序。

【讨论】:

双叉是另一回事,它实际上涉及 your 程序调用fork() 两次。 ***.com/questions/881388/…【参考方案6】:

您使用什么语言?一些语言有辅助方法,使守护进程更容易。例如,Ruby 有 daemons 包。

【讨论】:

以上是关于Linux 守护进程的主要内容,如果未能解决你的问题,请参考以下文章

linux怎么用守护进程和sdl

linux 如何将守护进程的日志写到自己指定的日志文件

在Linux部署进程守护脚本遇到的坑

Linux编程之《守护进程》

Linux 超级守护进程 xinetd

Linux系统中的守护进程讲解