[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

killing subprocess on exit

gga

2/22/2005 11:03:00 PM

I have an application that uses Open3.popen3 to run some -long running-
applications (on linux). Threads are then spawned to capture the
stdout/stderr of the application. This is all working fine.
However, I've noticed that ruby is not propagating the signals to its
child processes. That is, if the user happens to control-c my
application, the subprocesses started are not getting that signal and I
end up with some zombie processes running in the background.
I was wondering if:
a) this is normal behavior?
b) If so, how can I kill processes on exit or aborting, as popen3 does
not seem to give me their process ids.

1 Answer

Csaba Henk

2/23/2005 3:31:00 AM

0

On 2005-02-22, gga <GGarramuno@aol.com> wrote:
> I have an application that uses Open3.popen3 to run some -long running-
> applications (on linux). Threads are then spawned to capture the
> stdout/stderr of the application. This is all working fine.
> However, I've noticed that ruby is not propagating the signals to its
> child processes. That is, if the user happens to control-c my
> application, the subprocesses started are not getting that signal and I
> end up with some zombie processes running in the background.
> I was wondering if:
> a) this is normal behavior?
> b) If so, how can I kill processes on exit or aborting, as popen3 does
> not seem to give me their process ids.

Open3.popen3 doesn't leave zombies -- it forks twice. Children spawns a
grandchild, then exits, and the real stuff is done by the grandchild
(who gets orphaned, and thus init will be designated as a new parent).

Yep, neither Open3.popen3, nor IO.popen gives you a mechanism to get
control over the child. The doubleforking technique of Open3.popen3 has
a price: this makes it impossible to get info by Process.wait or
Process.wait2; but even with IO.popen, you are not told about the pid of
the child, so you can't use these methods directly.

What you can do if you use IO.popen: set a handler for SIGCHLD (you can
make it to do a Process::wait2 thus leaving no zombies). You may then
check $?, which contains the Process::Status info of the last exited and
reaped child (there is no magic global variable holding the pid of the
last spawned child though, according to the Quickref,
http://www.zenspider.com/Languages/Ruby/Qui...). If it's a
problem that $? gets overwritten all the time, you can make your signal
handler also to store the process infos in some global container.

Stay tuned, I'm at the polishing stage of a general piping class, which
gives you full control over your child processes, and many more. Its
soon to be announced in this list.

In the meantime, you may also use "shell":

require 'shell'
sh = Shell.new
sh.transact { system("echo a") | system("tr a A") }

It also reaps children. I don't know how much reflection it gives you on
children's lifecycle, or how exactly can you communicate with children, though.

Csaba