2014-01-28 28 views
0

有没有一种方法可以让Ruby进程/线程自行暂停,直到它由某个外部进程的信号(或其他进程间通信机制)恢复?我试过以下,但线程似乎并没有被唤醒:Ruby等待来自外部进程的信号

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! =)" 

实例运行:

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

我也试过以下,它的作品,但依赖于连续地检查一些变量,我宁愿以避免如果可能的值:

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! =)" 

实施例运行:

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

回答

0

你可以使用at_exit做到这一点:

at_exit do 
    puts "Now awake! =)" 
end 

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

puts "Going to sleep..." 
sleep 

实例运行:

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

哈哈。不错的尝试,但我真的需要该程序在醒来后实际上继续运行。 :P接收信号后,我的真实程序还有很多事情要比打印“Now awake!=)”更好,然后退出。 – Ajedi32

+0

那么你可以把所有这些都放到你在'at_exit'块中调用的方法中;-)但是我明白你的意思 - 能够多次停止和恢复会很好。 –

1

这是三年左右的时间较晚,但可能会为未来的读者会有所帮助:

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! =)" 

这将paus e主线程并等待USR1信号。它打印出可用于唤醒线程的命令。在我的系统上,这打印

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

Waking up! 
Now awake! =)