在Ruby中用双叉创build一个守护进程

在Ruby中创build一个运行良好的Unix或Linux守护进程的正确方法是什么?

无论如何,一个行为良好的守护进程的定义是什么?如何在Ruby中编写这样的程序?

Solutions Collecting From Web of "在Ruby中用双叉创build一个守护进程"

根据Stevens 在UNIX环境下高级编程第13章,这是制作一个运行良好的Unix守护进程的过程:

  1. 叉,并有父母出口。 这使shell或启动脚本认为命令完成。 另外,子进程保证不成为进程组的领导者(下一步为setsid的前提条件)
  2. 调用setsid创建一个新的会话。 这有三件事情:
    1. 这个过程成为新会议的会议领导
    2. 这个过程成为一个新的过程组的过程组长
    3. 这个过程没有控制终端
  3. 或者再次分叉,并有父级退出。 这保证守护进程不是会话负责人,也不能获得控制终端(在SVR4下)
  4. 将当前工作目录更改为/以避免干扰挂载和卸载
  5. 将文件模式创建掩码设置为000以允许稍后创建具有任何所需权限的文件。
  6. 关闭从父项继承的不需要的文件描述符(无论如何都没有控制终端): stdoutstderrstdin

现在有一个文件来跟踪Linux分发引导脚本严重使用的PID。 一定要写出孙子的PID,第二个分支的返回值(步骤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 

继贾森的真棒回应后,我写了一个更完整的实现:

https://gist.github.com/1372491/b76b60fb1842bf0507f47869ab19ad50a045b214

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

另一个有趣的实施是在独角兽:

https://github.com/defunkt/unicorn/blob/master/lib/unicorn/launcher.rb