Ajedi32
Ajedi32

Reputation: 48368

Ruby wait for signal from external process

Is there a way to make a Ruby process/thread pause itself until it is resumed by a signal (or some other inter-process communication mechanism) from some external process? I've tried the following, but the thread doesn't seem to be waking up:

this_thread = Thread.current
Thread.new do
  Signal.trap("INT") do
    puts "\nWaking up!"
    this_thread.run
  end
  sleep
end

puts "Going to sleep..."
Thread.stop
puts "Now awake! =)"

Example run:

$ ruby wake_on_signal.rb 
Going to sleep...
^C
Waking up!
^C
Waking up!
^C
Waking up!

I've also tried the following, which works but is dependant on continuously checking the value of some variable, which I'd prefer to avoid if possible:

signal_received = false
Signal.trap("INT") do
  puts "\nWaking up!"
  signal_received = true
end

puts "Going to sleep..."
sleep 0.5 until signal_received
puts "Now awake! =)"

Example run:

$ ruby sleep_until_signal.rb 
Going to sleep...
^C
Waking up!
Now awake! =)

Upvotes: 0

Views: 1301

Answers (2)

Sasha
Sasha

Reputation: 31

This is about three years late, but might be helpful for future readers:

puts "kill -#{Signal.list["USR1"]} #{Process.pid}"
thr = Thread.new do
    this_thread = Thread.current
  Signal.trap("USR1") do
    puts "\nWaking up!"
    this_thread.kill
  end
  sleep
end

puts "Going to sleep..."
thr.join
puts "Now awake! =)"

This will pause the main thread and wait for the USR1 signal. It prints out the command that you can use to wake up the thread. On my system, this prints

$ ruby signal_handler.rb
kill -30 66771  
Going to sleep...

Waking up!
Now awake! =)

Upvotes: 3

Patrick Oscity
Patrick Oscity

Reputation: 54684

You could use at_exit to do this:

at_exit do
  puts "Now awake! =)"
end

Signal.trap("INT") do
  puts "\nWaking up!"
  exit
end

puts "Going to sleep..."
sleep

Example run:

$ ruby wake_on_signal.rb 
Going to sleep...
^C
Waking up!
Now awake! =)

Upvotes: 0

Related Questions