Skip to content

Instantly share code, notes, and snippets.

@robvinson
Created August 28, 2012 21:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robvinson/3504621 to your computer and use it in GitHub Desktop.
Save robvinson/3504621 to your computer and use it in GitHub Desktop.
ruby preforking test program
#!/usr/bin/env ruby
# The trap is guaranteed to happen, and guaranteed to happen only
# once, right before the process exits for any reason (unless
# it's terminated with a SIGKILL).
#trap('EXIT') { acceptor.close }
CONTROL = []
CONTROL[0], CONTROL[1] = IO.pipe
WORKERS = []
# this gets executed in a child process
def worker_loop
# now we're in the child process; trap (Ctrl-C) interrupts and
# exit immediately instead of dumping stack to stderr.
trap('INT') { exit }
# Close the reading end of the pipe, we don't need this in the child
CONTROL[0].close
wpid = Process.pid
loop {
ret = IO.select([STDIN],nil,nil,5)
puts "#{wpid} after select"
begin
if ret
stuff = STDIN.read_nonblock(2046)
puts "#{wpid} #{stuff}"
sleep 1
end
# Write a heartbeat to the pipe, if the parent dies
# we'll get an error since the other side of the pipe is gone.
# This error is used to terminate the children if the parent dies.
CONTROL[1].write('.')
rescue Errno::EAGAIN
redo
rescue Errno::EPIPE
puts "#{wpid} Parent died... shutting down..."
exit # the parent must have died so we should go away too
end
}
end
puts "parent is #{Process.pid}"
3.times do
if pid = fork
# we're in the parent here, save the worker pid
WORKERS << pid
else
# we're in the child, start up the worker loop
worker_loop
exit
end
end
# Close the writing end of the pipe, we don't need this in the parent
CONTROL[1].close
trap('INT','TERM') { CONTROL[0].close; exit }
# Sit back and wait for all child processes to exit.
Process.waitall
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment