Linux守护进程

Linux守护进程,linux,daemon,Linux,Daemon,我正在编写一个Linux守护程序。我找到了两种方法 通过调用fork()并设置sid来监视进程 使用和运行程序 哪种方法正确?实际上,要创建守护进程,必须使用双叉 使用&运行程序会使shell在后台运行程序,而不会使其成为守护进程。守护进程将init(pid 1)作为父进程,这就是为什么需要双分叉 因此,如果您的程序是一个守护进程,那么最好的方法就是自己处理这个问题(还有更多方法,请参阅)。您还可以使用启动-停止守护程序。第一个。第二个不是后台监控,而是在后台运行。Daemonized程序应位于

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

  • 通过调用
    fork()
    并设置
    sid
    来监视进程
  • 使用
    运行程序

  • 哪种方法正确?

    实际上,要创建守护进程,必须使用双叉

    使用&运行程序会使shell在后台运行程序,而不会使其成为守护进程。守护进程将init(pid 1)作为父进程,这就是为什么需要双分叉


    因此,如果您的程序是一个守护进程,那么最好的方法就是自己处理这个问题(还有更多方法,请参阅)。您还可以使用启动-停止守护程序。

    第一个。第二个不是后台监控,而是在后台运行。Daemonized程序应位于其自己的会话和进程组中,并且不应具有控制终端。

    来自

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

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

  • 更好的是,如果函数可用,只需调用它。

    您使用的是什么语言?某些语言具有帮助器方法,使后台监控更容易。例如,Ruby有这个包。

    只需使用(从
    unistd.h

    daemon()函数用于程序 希望脱离现实 控制终端并在 后台作为系统守护进程


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


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

    但我仍然无法理解设置自己的会话和进程组有什么用您必须关闭所有打开的描述符。否则,文件可能会继续具有引用,例如,这将阻止删除它们。这很像chdir(“/”。@n-alexanderso-daemon()是双叉吗?Ruby WEBrick daemonize(切换源代码)中的一个很好的例子:daemon()可能无法在Linux上正常工作。daemon()手册页中:“此函数的GNU C库实现取自BSD,并且没有采用双叉技术(即fork(2)、setId(2)、fork(2)),这是确保生成的守护进程不是会话引导进程所必需的。相反,生成的守护进程是会话引导进程。”+1。至少,提供在前台运行的选项。很抱歉带来一个旧的答案,但是monit也可以作为守护进程启动您的进程吗?您可以使用nohup:我花了几天时间研究如何使用jenkins在ubuntu上作为守护进程运行flask应用程序,直到我看到您的建议。非常感谢。我的问题通过shell命令export BUILD\u ID=dontKillMe解决了
    daemon flask run
    Double fork是另外一回事,它实际上涉及到程序调用
    fork()
    两次。