2

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

我的模拟是:

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

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

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

4

1 回答 1

1

好的,大家。我觉得打字有点愚蠢,因为我在五分钟后找到了一个解决方案(我在 Stack Overflow 上忽略了一个)。

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

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

这设法实现了我本质上想要做的事情。

谢谢阅读!

于 2013-05-14T22:57:27.427 回答