【问题标题】:how do i run an asynchronous loop in ruby?如何在 ruby​​ 中运行异步循环?
【发布时间】:2014-06-18 06:50:42
【问题描述】:

我需要执行一个运行多个管理系统命令的进程。我想在运行时保持 sudo 时间戳最新,以防进程运行时间过长。

我有以下代码,但它似乎不起作用。

sudo_keep_alive = Thread.start do
  def sudo
    sleep 5.minutes
    `sudo -v`
    sudo
  end
  sudo
end

at_exit do
  sudo_keep_alive.kill
end

这有约定吗?

更新

我无法运行脚本的原因是root,脚本运行的其他系统命令无法以root身份运行。每个命令都需要负责运行它自己的管理命令。该脚本可能需要相当长的时间才能运行,所以我只是想在命令需要时保持 sudo 时间戳的最新状态。

【问题讨论】:

  • 为什么不用sudo 运行你的ruby 脚本?
  • 没有多大意义。首先,您需要以更系统的方式保持 sudo 凭据,而不是使用这种黑客攻击。其次,您的线程将与主进程同时死亡,因此向 Kernel.at_exit 注册是没有意义的。

标签: ruby asynchronous


【解决方案1】:

要回答您的其他问题,有一种更好的方法来运行异步循环。

通过使用头尾递归 (def sudo; do_something; sudo; end),您可能会在大约 10000 次调用时遇到 SystemStackError(请参阅 How does your favorite language handle deep recursion?)。

相反,只需使用常规的旧 ruby​​ 循环。

Thread::new do
  loop do
    sleep 300 # 5.minutes is not base ruby, it comes from ActiveSupport
    call_my_function
  end
end

正如 David Unric 所说,无需使用 at_exit 终止线程,因为您的主进程将在完成时自动终止所有活动线程。

【讨论】:

    【解决方案2】:

    放弃所有这些并以 root 身份执行您的 ruby​​ 脚本。

    $ sudo ruby myscript.rb
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-12
      • 1970-01-01
      • 1970-01-01
      • 2020-05-23
      • 1970-01-01
      • 2018-07-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多