[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: speeding up Process.detach frequency

Gary Wright

6/26/2005 3:53:00 PM


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



3 Answers

nobu.nokada

6/26/2005 11:17:00 PM

0

Hi,

At Mon, 27 Jun 2005 00:53:04 +0900,
gwtmp01@mac.com wrote in [ruby-talk:146522]:
> 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):

Open3 does it and it makes impossible to get the result of the
given command.

--
Nobu Nakada


Gary Wright

6/27/2005 12:14:00 AM

0


On Jun 26, 2005, at 7:16 PM, nobu.nokada@softhome.net wrote:
> At Mon, 27 Jun 2005 00:53:04 +0900,
> gwtmp01@mac.com wrote in [ruby-talk:146522]:
>
>> 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):
>>
>
> Open3 does it and it makes impossible to get the result of the
> given command.

It depends what your goal is. If you want to start a child
process and capture output, interact with the process via IO,
or wait for the exit status you've got a variety of things to work with:

Kernel#`
Kernel#system
IO.popen
Open3#popen3

But if you aren't interested in capturing the output and/or
exit status of the children you probably are going to work with
fork/exec to establish a more typical "deamon" behavior where the
daemon process is completely disassociated from the parent process.
This is where the Process#daemon method I posted would be helpful.

Process.detach is a bit strange. It is used *after* the child
has already been forked, at which point there is nothing much that
#detach can do other than periodically wait on the child. It can't
double fork because the new child will be a sibling of the previous
child and not a parent.

It just seems strange to use Process.detach instead of some other
combination that avoids the whole busy wait problem in the first
place.


Gary Wright



Nakada, Nobuyoshi

6/27/2005 2:56:00 AM

0

Hi,

At Mon, 27 Jun 2005 09:14:13 +0900,
gwtmp01@mac.com wrote in [ruby-talk:146541]:
> This is where the Process#daemon method I posted would be helpful.

Process#daemon has been implemented already.

> Process.detach is a bit strange. It is used *after* the child
> has already been forked, at which point there is nothing much that
> #detach can do other than periodically wait on the child. It can't
> double fork because the new child will be a sibling of the previous
> child and not a parent.

Its purpose and usage are different from Process#daemon, so I
think double fork doesn't solve the issue about detaching.
Detaching a process is not so strange, bash has `disown'
built-in command for instance.

--
Nobu Nakada