From: Robert Klemme Date: 2013-01-25T05:33:24+09:00 Subject: Re: Processes and forks On Thu, Jan 24, 2013 at 6:56 PM, Carlo E. Prelz wrote: > The biggest reason why your process does not die is most probably > because you use system (which starts a shell). The signal reaches the > shell but not gdb. I don't think there is a signal at all because system just blocks until the process dies and the timeout exception is raised *after* the process has terminated and control comes back into the Ruby interpreter. Proof: Test script: $ cat k.sh #!/usr/bin/bash echo "PID $$" for i in {0..30}; do trap "echo signal $i" $i done read -p ENTER # block Demo to show signal output via pressing Ctrl-C: $ ./k.sh PID 2296 ENTERsignal 2 signal 2 signal 2 signal 2 signal 0 Now with Timeout: $ time ruby -r timeout -e 'Timeout.timeout(2) { system "./k.sh" }' PID 3552 ENTER signal 0 -e:1:in `system': execution expired (Timeout::Error) from -e:1:in `block in
' from -e:1:in `
' real 0m18.096s user 0m0.046s sys 0m0.201s As you can see from real time I waited much longer than the timeout of 2 seconds before I pressed enter. > So, instead of system, you should use Process::spawn. But even then, > read carefully the doc: if you pass a command line (like in your > example), you will still have a shell process in the middle. To avoid > that, you must pass the parts of the command in an array. Every time I > do this, I have to spend a decent amount of time finding how to > correctly split the command. That's generally good advice but I believe in this case not important for the issue (see above). > Anyway, you may try with something like: > > pid=Process::spawn(array) > > begin > Timeout::timeout(5) do > Process::waitpid(pid) > end > rescue Timeout::Error > Process::kill(pid,'KILL') > Process::waitpid(pid) > end That looks like a good solution. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/