2014-01-28 29 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! =)