在Ruby中创建具有双fork的守护程序

在Ruby中创建具有双fork的守护程序,ruby,linux,unix,fork,daemon,Ruby,Linux,Unix,Fork,Daemon,在Ruby中创建行为良好的Unix或Linux守护程序的正确方法是什么? 行为良好的守护进程的定义是什么?人们将如何用Ruby编写这样的程序?根据Stevens在UNIX环境中的高级编程第13章,这是创建行为良好的UNIX守护进程的过程: Fork并让父级退出。这使shell或引导脚本认为命令已完成。此外,保证子流程不是流程组长(setsid next的先决条件) 调用setsid创建新会话。这有三件事: 流程将成为新会话的会话主管 流程将成为新流程组的流程组长 该过程没有控制终端 (可选)再

在Ruby中创建行为良好的Unix或Linux守护程序的正确方法是什么?

行为良好的守护进程的定义是什么?人们将如何用Ruby编写这样的程序?

根据Stevens在UNIX环境中的高级编程第13章,这是创建行为良好的UNIX守护进程的过程:

  • Fork并让父级退出。这使shell或引导脚本认为命令已完成。此外,保证子流程不是流程组长(setsid next的先决条件)
  • 调用
    setsid
    创建新会话。这有三件事:
  • 流程将成为新会话的会话主管
  • 流程将成为新流程组的流程组长
  • 该过程没有控制终端
  • (可选)再次分叉并使父级退出。这保证了守护进程不是会话领导者,也不能获取控制终端(在SVR4下)
  • 将当前工作目录更改为
    /
    ,以避免干扰装载和卸载
  • 将文件模式创建掩码设置为000,以允许稍后创建具有任何所需权限的文件
  • 关闭从父级继承的不需要的文件描述符(反正没有控制终端):
    stdout
    stderr
    stdin
  • 现在有一个文件跟踪PID,Linux发行版引导脚本大量使用该文件。确保写出孙子的PID,第二个fork的返回值(步骤3)或步骤3之后
    getpid()
    的值

    这是一个Ruby实现,大部分是从书中翻译过来的,但是使用了双叉并写出了守护进程PID

    # Example double-forking Unix daemon initializer.
    
    raise 'Must run as root' if Process.euid != 0
    
    raise 'First fork failed' if (pid = fork) == -1
    exit unless pid.nil?
    
    Process.setsid
    raise 'Second fork failed' if (pid = fork) == -1
    exit unless pid.nil?
    puts "Daemon pid: #{Process.pid}" # Or save it somewhere, etc.
    
    Dir.chdir '/'
    File.umask 0000
    
    STDIN.reopen '/dev/null'
    STDOUT.reopen '/dev/null', 'a'
    STDERR.reopen STDOUT
    

    根据Jason的精彩回复,我在这里编写了一个更完整的实现:

    除了双叉和将pid写入文件之外,我还实现了日志记录

    另一个有趣的实现是在Unicorn中:


    这确实是一个很好的解释!非常感谢您回答自己的问题。不是每个人都这样做,即使他们后来找到了解决问题的方法。但丁宝石似乎在内部这样做: