文件在进程恶魔化时重新打开

Files reopen on process demonization

我在Sidekiq中找到了下一段与进程妖魔化相关的代码:

  files_to_reopen = []
  ObjectSpace.each_object(File) do |file|
    files_to_reopen << file unless file.closed?
  end

  ::Process.daemon(true, true)

  files_to_reopen.each do |file|
    begin
      file.reopen file.path, "a+"
      file.sync = true
    rescue ::Exception
    end
  end

  [$stdout, $stderr].each do |io|
    File.open(options[:logfile], 'ab') do |f|
      io.reopen(f)
    end
    io.sync = true
  end
  $stdin.reopen('/dev/null')

https://github.com/mperham/sidekiq/blob/master/lib/sidekiq/cli.rb#L191-L212

我不明白为什么我们在双叉上继承了文件描述符,为什么还要重新打开文件?是否存在某些特定案例可以做到这一点? "Advanced Programming in the UNIX Environment" 书的作者,第 "Daemon Processes" 章,说 关于关闭 不需要 文件描述符:

  1. Unneeded file descriptors should be closed. This prevents the daemon from holding open any descriptors that it may have inherited from its parent (which could be a shell or some other process). We can use our open_max function (Figure 2.17) or the getrlimit function (Section 7.11) to determine the highest descriptor and close all descriptors up to that value.

我相信大部分代码都受到了 Unicorn 的启发。 Unicorn 的作者 Eric Wong 是 Ruby 世界的 Linux 先生,通常知道正确执行守护进程的所有技巧。

当然,从大局来看,不要守护进程。您应该使用合适的进程主管启动 Sidekiq:systemd、upstart、runit、foreman 等。