Ruby无限循环中的用户中断(多个类)?

时间:2013-05-14 22:37:09

标签: ruby multithreading user-input

我发现了另一个与我非常相似的问题,当我用一个简单的脚本编写它时,这个解决方案对我有用。我甚至写了第二个简单的例子来模拟我正在尝试做的事情,它似乎仍然有效。

我的模拟是:

class A
  def looper(&block)
    Thread.new do
      loop do
        exit if gets.chomp == 'q'
      end
    end
    loop do
      block.call
    end
  end
end

class B < A
  def looper
    super do
      puts 'howddyyyy from B'
    end
  end
end

这样可以正常工作,当您按q<Enter>时退出。但是,当我尝试将其实现到我的实际项目中时,它无法工作。我将在子类中发布相关方法中的代码,因为父类与上面的示例完全相同。

def looper
  super do
    if obj = Object.first(:process_status => STATUS_UNPROCESSED)
      puts "[Object ##{obj.id}] Processing..."
      puts "-" * 60

      obj.set_failed
      if @obj.process(obj)
        obj.set_processed
      end

      puts "-" * 60
      puts "[Object ##{obj.id}] Finished!"
      puts
      puts
    else
      sleep 10
    end
  end
end

因此,出于某种原因,这不起作用。我将puts放入新线程(监听q),它似乎在block.call的每个循环之前输出了放置。也许它只是无法获得密钥,我的意思是,您可能需要输入q<Enter>的时间范围太小?我不确定,这就是我在这里提出一些建议的原因。我唯一的另一个猜测是它与 in 这个方法(进程,或可能是Sequel对数据库的调用)阻塞其他线程的方法有关?

我是线程新手,所以我不知道。

1 个答案:

答案 0 :(得分:1)

好的,大家好因为我在五分钟之后找到了一个解决方案(而且我在Stack Overflow上忽略了一个解决方案),我觉得因为输入所有内容而感到有点愚蠢。

对于任何未来面临类似问题的人来说,这就是我最终做的事情(在父类中):

def looper(&block)
  interrupted = false
  trap("INT") { interrupted = true }
  until interrupted do
    block.call
  end
  exit
end

这可以实现我本来想要做的事情。

感谢阅读!