Forum: Ruby Please kill the children as you're leaving

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
426d8be2204a36c4e609ace097d7c554?d=identicon&s=25 Ohad Lutzky (Guest)
on 2006-06-04 13:47
Sorry about the Macabre, but that's essentially what I want: It seems
that children of my process (created using fork) get reparanted to init
when my process dies unexpectedly. I'd like to have them all die on the
spot instead (not wait for them to finish - kill them on the spot). How
do I do this?

I assume it would have to do with a big begin/rescue/end block around
the whole app...
426d8be2204a36c4e609ace097d7c554?d=identicon&s=25 Ohad Lutzky (ohad)
on 2006-06-04 15:14
Allow me to clarify the problem. Say I use irb as follows:

  fork do
    { } while true
  end
=> SOME_PID

Now, if I kill (externally) the parent irb, then SOME_PID dies along
with it. However, if instead of doing that, I

  raise Exception

Then the child lives, reparanted to init. How do I avoid that?
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2006-06-04 15:32
(Received via mailing list)
2006/6/4, Ohad Lutzky <lutzky@gmail.com>:
>   raise Exception
>
> Then the child lives, reparanted to init. How do I avoid that?

You can either have a beginn rescue end block on your top level or you
use at_exit to deal with the situation, i.e. kill children:

http://www.ruby-doc.org/core/classes/Kernel.html#M002953

Kind regards

robert
481b8eedcc884289756246e12d1869c1?d=identicon&s=25 Francis Cianfrocca (Guest)
on 2006-06-04 16:37
(Received via mailing list)
How does your parent process die unexpectedly? If it catches signal 9,
for
example, your atexit handlers won't run. You could try something
dramatic
like open a socketpair between parent and child processes (don't forget
to
turn off CLOEXEC for forking) and then have the child processes
periodically
send a byte to the parent. If you lose the parent, then the write from
the
child should catch SIGPIPE. Also possible is for the children to
periodically to check the status of the parent process (getppid).
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-06-04 17:17
(Received via mailing list)
On Sun, 4 Jun 2006, Francis Cianfrocca wrote:

> How does your parent process die unexpectedly? If it catches signal 9, for
> example, your atexit handlers won't run. You could try something dramatic
> like open a socketpair between parent and child processes (don't forget to
> turn off CLOEXEC for forking) and then have the child processes periodically
> send a byte to the parent. If you lose the parent, then the write from the
> child should catch SIGPIPE. Also possible is for the children to
> periodically to check the status of the parent process (getppid).

indeed.  this is exactly what my slave library does - it sets up a
heartbeat
pipe between parent and child.  this way, even if the parent dies via
'kill
-9', which no code can handle, the child will die.  eg.

   harp:~ > cat a.rb
   # http://codeforpeople.com/lib/ruby/slave/
   require 'slave'

   class Child
     def initialize
       @pid = Process.pid
       Thread.new{loop{warn "child <#{ @pid }> @ <#{ Time.now }>"; sleep
1}}
     end
   end

   class Parent
     def initialize
       @pid = Process.pid
       @child = Slave.new(Child.new)
       sleep 3
       Process.kill -9, @pid
     end
   end

   Parent.new


   harp:~ > ruby a.rb
   child <26196> @ <Sun Jun 04 09:11:17 MDT 2006>
   child <26196> @ <Sun Jun 04 09:11:19 MDT 2006>
   child <26196> @ <Sun Jun 04 09:11:20 MDT 2006>
   Killed


ps.  the gem for slave is on rubyforge but, for some reason, a 'gem
install
slave' does not work.  you can download the gem manually here:

   http://rubyforge.org/frs/?group_id=1024&release_id=5464

pss.  this is setup exactly like all the other projects under
codeforopeople -
if anyone has any ideas on why slave installs fail please contact me
offline.

cheers.

-a
0ca6e5c33d7e7ff901d75ff0b13d9e1c?d=identicon&s=25 Sam Roberts (Guest)
on 2006-06-05 01:52
(Received via mailing list)
Quoting lutzky@gmail.com, on Sun, Jun 04, 2006 at 10:15:08PM +0900:
>   raise Exception
>
> Then the child lives, reparanted to init. How do I avoid that?

Non with irb, but you may be able to make the parent a session leader,
which might cause SIGHUP to be delivered to its children when it exits.

Do some reading on sessions, setsid(), and forground process groups.

Other ways would depend on why you want to do this. You could create a
pipe, and have all your children keep a thread blocked on the read end
of it, so when the parent dies, the write end is closed, and all the
read ends return with an error.

Sam
481b8eedcc884289756246e12d1869c1?d=identicon&s=25 Francis Cianfrocca (Guest)
on 2006-06-05 03:05
(Received via mailing list)
>>>Non with irb, but you may be able to make the parent a session leader,
which might cause SIGHUP to be delivered to its children when it exits.

If a process becomes a process group leader (setpgid(0,0) in the child
process after the fork and before it calls exec), then its parent can
kill
it and all of its subprocesses by sending a signal to the negative of
its
pid. Not sure that helps here though. The best idea I've heard so far is
for
the child processes to periodically write a pipe that terminates in the
parent. Then if the parent goes, the children will get killed by
SIGPIPE.

This stuff is pretty hard to get right, have to admit.
0ca6e5c33d7e7ff901d75ff0b13d9e1c?d=identicon&s=25 Sam Roberts (Guest)
on 2006-06-05 07:22
(Received via mailing list)
Quoting garbagecat10@gmail.com, on Mon, Jun 05, 2006 at 10:02:30AM
+0900:
> >>>Non with irb, but you may be able to make the parent a session leader,
> which might cause SIGHUP to be delivered to its children when it exits.
>
> If a process becomes a process group leader (setpgid(0,0) in the child
> process after the fork and before it calls exec), then its parent can kill
> it and all of its subprocesses by sending a signal to the negative of its
> pid. Not sure that helps here though. The best idea I've heard so far is for

Advance Programming in the Unix Environment, p.267 (R. Stevens) says:

  SIGHUP .... This signal is also generated if the session leader
  terminates. In this case, the signal is sent to each process in the
  foreground process group.

It sounds like it should be possible to arrange for sighup to be sent to
an entire process group automatically if the session leader terminates.

Cheers,
Sam
481b8eedcc884289756246e12d1869c1?d=identicon&s=25 Francis Cianfrocca (Guest)
on 2006-06-05 11:05
(Received via mailing list)
>>>>>>>>>>>

> Advance Programming in the Unix Environment, p.267 (R. Stevens) says:
>
>   SIGHUP .... This signal is also generated if the session leader
>   terminates. In this case, the signal is sent to each process in the
>   foreground process group.
>
> It sounds like it should be possible to arrange for sighup to be sent to
> an entire process group automatically if the session leader terminates.
> <<<<<<<<<<<<




You get this automatically. I assumed that the OP was raising the issue
because he's running in some environment (like a daemon or a cron job)
where
there is no controlling tty or foreground process group.
3a3fe02be09e3103aea5e22d62478f38?d=identicon&s=25 Pedro Côrte-Real (Guest)
on 2006-06-05 15:36
(Received via mailing list)
On 6/4/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:
> ps.  the gem for slave is on rubyforge but, for some reason, a 'gem install
> slave' does not work.  you can download the gem manually here:
>
>    http://rubyforge.org/frs/?group_id=1024&release_id=5464
>
> pss.  this is setup exactly like all the other projects under codeforopeople -
> if anyone has any ideas on why slave installs fail please contact me offline.

Probably because the version number is 0.0.0 and gem looks for >0 when
installing something.

Pedro.
This topic is locked and can not be replied to.