Linux守护进程

我在写一个Linux守护进程。 我find了两种方法来做到这一点。

  1. 通过调用fork()并设置sid守护进程。
  2. &运行你的程序。

哪个是正确的做法?

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

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

  1. fork()所以父母可以退出,这将控制返回到命令行或shell调用您的程序。 这一步是必需的,以确保新stream程不会成为stream程组的领导者。 如果你是一个stream程组组长,下一步,setsid()将失败。
  2. setsid()成为进程组和会话组的领导者。 由于控制terminal与会话相关联,并且这个新的会话还没有获得控制terminal,所以我们的过程现在没有控制terminal,这对守护进程来说是一件好事。
  3. fork(),所以父(会话组领导)可以退出。 这意味着我们作为非会议组织的领导者,永远不能重新获得控制terminal。
  4. chdir(“/”)来确保我们的进程不保留任何目录的使用。 如果不这样做,可能会导致pipe理员无法卸载文件系统,因为这是我们当前的目录。 [相当于,我们可以更改为包含守护进程操作重要文件的任何目录。]
  5. umask(0),以便我们完全控制我们写的任何东西的权限。 我们不知道我们可能inheritance了什么。 [这一步是可选的]
  6. close()fds 0,1和2.这将释放我们从父进程inheritance的标准input,输出和错误。 我们无法知道这些fds可能被redirect到哪里。 请注意,许多守护进程使用sysconf()来确定_SC_OPEN_MAX的限制。 _SC_OPEN_MAX告诉你最大的打开文件/进程。 然后在一个循环中,守护进程可以closures所有可能的文件描述符。 你必须决定是否需要这样做。 如果您认为可能有文件描述符打开,则应closures它们,因为并发文件描述符的数量有限制。
  7. 为stdin,stdout和stderrbuild立新的开放描述符。 即使你不打算使用它们,打开它仍然是一个好主意。 精确处理这些是品味的问题; 例如,如果你有一个日志文件,你可能希望打开它作为stdout或stderr,并打开“/ dev / null”作为标准input; 或者,您可以打开“/ dev / console”作为stderr和/或标准输出,“/ dev / null”作为标准input,或者其他适合您的特定守护进程的组合。

更好的是,只要调用守护进程()函数即可。

我build议不要把程序写成守护进程。 使它在文件描述符,当前目录,进程组等给予它在前台运行。

如果你想以一个守护进程运行这个程序,可以使用start-stop-daemon(8),init(8),runsv(来自runit),upstart,systemd或其他来启动你的进程作为守护进程。 也就是说,让你的用户决定如何运行你的程序,而不是强制它作为一个守护进程运行。

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

守护进程()函数用于希望与控制terminal分离并作为系统守护进程在后台运行的程序。 …

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

其实要做一个守护进程你必须双叉。

用一个&运行程序让shell在后台运行程序,这并不是一个守护进程。 守护进程具有init(pid 1)作为父项,这就是为什么需要双叉。

所以,如果你的程序是一个守护进程,那么做事的好方法就是亲自处理这个问题(还有更多的方法,请看这里 )。 你也可以使用start-stop-daemon程序。

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