繁体   English   中英

如何让Ruby脚本每秒运行一次?

[英]How do I make a Ruby script run once a second?

我有一个需要每秒运行一次的Ruby脚本。 我使用Ruby脚本来跟踪目录中文件的修改,并希望脚本在“实时”时间内跟踪更新。

基本上,我希望我的脚本能够像在Unix shell上运行“top”一样运行,其中屏幕每隔一秒左右更新一次。 在Ruby中是否存在与Ruby中的setInterval相同的东西?

有几种方法可以做到这一点。

快速和肮脏的版本:

  1. 贝壳(kornish):

     while :; do my_ruby_script.rb sleep 1 done 
  2. (1)看:

     shell$ watch -n 1 my_ruby_script.rb 

    这将每秒运行您的脚本并保持终端中显示的最新运行的输出。

  3. 在红宝石:

     while true do_my_stuff sleep 1 end 

这些都遭受同样的问题:如果实际的脚本/函数需要时间来运行,它会使循环运行少于每秒。

这是一个ruby函数,只要函数不超过一秒钟,就会确保函数(几乎)每秒都被调用一次:

def secondly_loop
    last = Time.now
    while true
        yield
        now = Time.now
        _next = [last + 1,now].max
        sleep (_next-now)
        last = _next
    end
end

像这样使用它:

secondly_loop { my_function }

你可能会感兴趣这种宝石每当

您可以这样编码重复任务:

every 1.second do
  #your task
end

正如另一个答案所述,rb-inotify非常适合这类事情。 如果您不想使用它,那么一个简单的方法是使用线程:

a = Thread.new { loop { some_method; Thread.stop } }
b = Thread.new { loop { sleep 1; break unless a.alive?; a.run } }

要停止查询,使用a.kill或者确保some_method杀死自己的线程与Thread.kill当某些条件得到满足。

使用这样的两个线程可确保some_method至少每秒运行一次,无论操作的长度如何,无需任何时间检查自己(当然,在线程调度的粒度内)。

您可能需要考虑使用rb-inotify之类的东西来获取文件更改的通知。 这样你就可以避免“睡觉”并保持“活”的感觉。

Guard Gem文档的“高效文件系统处理”部分提供了一些有用的信息: https//github.com/guard/guard#efficient-filesystem-handling

或者您可以使用Concurrent Ruby gem中的TimerTask

timer_task = Concurrent::TimerTask.new(execution_interval: 1) do |task|
  task.execution_interval.times{ print 'Boom! ' }
  print "\n"
  task.execution_interval += 1
  if task.execution_interval > 5
    puts 'Stopping...'
    task.shutdown
  end
end

timer_task.execute

从同一链接中提取的代码

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM