diff options
| author | mo khan <mo@mokhan.ca> | 2013-08-28 07:20:13 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2013-08-28 07:20:13 -0600 |
| commit | db1191ec0e7305d684383f8974e2fa437f77ad5a (patch) | |
| tree | 5e27b197dff849d22d8e1f50eb75aa499b16bd06 /code/snippets/signals_chld_nohang.rb | |
Diffstat (limited to 'code/snippets/signals_chld_nohang.rb')
| -rw-r--r-- | code/snippets/signals_chld_nohang.rb | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/code/snippets/signals_chld_nohang.rb b/code/snippets/signals_chld_nohang.rb new file mode 100644 index 0000000..621a70c --- /dev/null +++ b/code/snippets/signals_chld_nohang.rb @@ -0,0 +1,42 @@ +child_processes = 3 +dead_processes = 0 +# We fork 3 child processes. +child_processes.times do + fork do + # They sleep for 3 seconds. + sleep 3 + end +end + +# Sync $stdout so the call to #puts in the CHLD handler isn't +# buffered. Can cause a ThreadError if a signal handler is +# interrupted after calling #puts. Always a good idea to do +# this if your handlers will be doing IO. +$stdout.sync = true + +# Our parent process will be busy doing some intense mathematics. +# But still wants to know when one of its children exits. + +# By trapping the :CHLD signal our process will be notified by the kernel +# when one of its children exits. +trap(:CHLD) do + # Since Process.wait queues up any data that it has for us we can ask for it + # here, since we know that one of our child processes has exited. + + # We loop over a non-blocking Process.wait to ensure that any dead child + # processes are accounted for. + begin + while pid = Process.wait(-1, Process::WNOHANG) + puts pid + dead_processes += 1 + end + rescue Errno::ECHILD + end +end + +loop do + # We exit ourself once all the child processes are accounted for. + exit if dead_processes == child_processes + + sleep 1 +end |
