From: gwtmp01@... Date: 2005-06-27T00:53:04+09:00 Subject: Re: speeding up Process.detach frequency On Jun 26, 2005, at 6:28 AM, Yukihiro Matsumoto wrote: > In message "Re: speeding up Process.detach frequency" > on Sun, 26 Jun 2005 13:39:35 +0900, nobu.nokada@softhome.net > writes: > |> |It seems like a bug of Process.detach. After it received the > |> |termination, it unnecessarily waits for one second again. > |> > |> Right. But using rb_waitpid() withouth WNOHANG does busy-wait. > | > |It should check periodically once per 0.06sec in > |rb_thread_polling(). > > Isn't it too often for most of the cases? If the goal is simply to prevent zombie processes, then Process#detach should just do a double fork. Here is an implementation of that technique along with a couple other issues that are common when creating a detached process (a daemon in Unix terminology): def Process.daemon(dir="/") return nil unless pid = fork { setsid # become session leader of new session group fork { # second fork, ensures child is *not* the session leader # then throw away references to the terminal or any other # redirections. [$stdin, $stdout, $stderr].each { |io| io.close } Dir.chdir(dir); File.umask(0) yield if block_given? } exit(0) } wait(pid) end Standard practice is for a daemon is to close all open file descriptors and then reopen what files are relevent for the daemon (log files usually). Above I just closed stdin/out/err. You could loop through all the open files and close them. This method will make it easy to reopen stdin/stdout/stderr to the locations expected by the daemon: def Process.reopen(stdin=nil, stdout=nil, stderr=stdout) $stdin = File.open(stdin || "/dev/null", "r") $stdout = File.open(stdout || "/dev/null", "w") $stderr = File.open(stderr || "/dev/null", "w") end Here is an example of using these two calls Process.daemon { Process.reopen(nil, "/tmp/logfile") sleep 5; puts "this goes to /tmp/logfile" } The interface to reopen could be different. Gary Wright