我正在尝试为我的CLI应用程序执行信号处理。我想避免自管“技巧”,但也考虑使用定期轮询的每线程信号列表不是最好的主意。因此,我的想法是使用Queue
来阻止直到新信号到来。这是我的尝试:
class CLI
def initialize
@manager = Thread.new { sleep }
@signal_queue = Queue.new
setup_signal_handlers
end
def run
loop do
signal = @signal_queue.pop # This doesn't unblock!
handle_signal(signal)
end
rescue Interrupt
exit
end
private
def handle_signal(signal)
case signal
when 'INT'
raise Interrupt
end
end
def setup_signal_handlers
%w(INT).each do |signal|
trap signal do
@signal_queue.push signal # This works. @signal_queue.size is incremented
end
end
end
end
# Run with CLI.new.run and hit ctrl^C
我为了清晰起见简化了@manager
。问题是,即使信号被捕获并推送到@signal_queue
,阻塞呼叫@signal_queue.pop
也不会将其接收。我在这里缺少什么?
答案 0 :(得分:1)
看起来你正在遇到Ruby bug #12405: Queue doesn't work inside of trap。幸运的是,这个错误在Ruby版本2.2.7,2.3.4和2.4.1(2.5.0已经包含该修复)中得到修复;因此,在升级到更新的Ruby版本之后,您的代码将按预期运行。