简体   繁体   English

如何在ruby中运行异步循环?

[英]how do i run an asynchronous loop in ruby?

I need to execute a process that runs several admin system commands. 我需要执行一个运行几个管理系统命令的过程。 I want to keep the sudo timestamp current while it runs in case the process run too long. 我想在运行时将sudo时间戳保持最新,以防进程运行时间过长。

i have the following code, but it does not seem to work. 我有以下代码,但似乎无法正常工作。

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

Is there a convention for this? 为此有约定吗?

UPDATE UPDATE

The reason i cannot run the script has root, is there are other system commands the script runs that cannot run as root. 我无法运行脚本的原因是具有root用户权限,是否还有其他系统命令无法以root用户身份运行脚本。 Each command needs to be responsible for running it's own admin commands. 每个命令都需要负责运行自己的管理命令。 The script can potentially take a considerable amount of time to run, so i simply wanted to keep the sudo timestamp fresh in the event a command needs it. 该脚本可能会花费大量时间来运行,因此我只是想在命令需要时保持sudo时间戳最新。

废弃所有这些,然后以root身份执行ruby脚本。

$ sudo ruby myscript.rb

To answer your other question, there is a better way to run an asynchronous loop. 为了回答您的另一个问题,有一种更好的方法来运行异步循环。

By using head-tail recursion ( def sudo; do_something; sudo; end ) you risk running into a SystemStackError at around 10000 calls (see How does your favorite language handle deep recursion? ). 通过使用头尾递归( def sudo; do_something; sudo; end ),您冒着在大约10000次调用时遇到SystemStackError的风险(请参阅您喜欢的语言如何处理深度递归? )。

Instead, just use a regular old ruby loop. 相反,只需使用常规的旧红宝石循环即可。

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

As mentioned by David Unric, there is no need to kill the thread using at_exit , as your main process will automatically kill any active threads when it finishes. 正如David Unric提到的那样,无需使用at_exit杀死线程,因为您的主进程将在完成时自动杀死任何活动线程。

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

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