使用Ruby中的Queue进行信号处理

时间:2018-03-23 10:26:43

标签: ruby multithreading queue signals

我正在尝试为我的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也不会将其接收。我在这里缺少什么?

1 个答案:

答案 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版本之后,您的代码将按预期运行。