【问题标题】:How do you run ruby scripts from ruby simultaneously?如何同时从 ruby​​ 运行 ruby​​ 脚本?
【发布时间】:2013-03-12 19:20:23
【问题描述】:

我有一个名为 main.rb 的程序,我想执行以下操作:

system("ruby", "program1.rb")
sleep 60
system("ruby", "program2.rb")
sleep 60
system("ruby", "program3.rb")
sleep 60
system("ruby", "program4.rb")

puts "Programs are done running"

有没有办法在没有 program2 等到 program1 完成的情况下执行上述操作?我在想它可能必须为每个程序打开一个新的 CLI? 另外,我想仅在所有 4 个都完成后才输出“程序已完成运行”消息。有没有办法做到这一点? 谢谢!

【问题讨论】:

  • 虽然这是可行的,但根据对各种答案的 cmets,需要很多帮助才能让您走上正确的道路,以便能够做您想做的事。您需要了解线程、同步线程的输出或独立捕获它们的输出,然后将其重新组合成一条消息。这超出了 Stack Overflow 上单个问题的范围。

标签: ruby scripting command system


【解决方案1】:

您似乎希望每个程序同时运行,但希望在启动每个子程序之间等待 60 秒,然后等待所有程序完成。 Process::spawn 本质上是 system,但背景是返回其 pid 的子进程。这应该可以得到你想要的:

to_run = %w{program1.rb program2.rb program3.rb program4.rb}
pids = [ Process.spawn('ruby', to_run.first) ]
pids.concat to_run.drop(1).map{ |p| sleep(60); Process.spawn('ruby', p) }
Process.waitall
puts 'Everything done!'

如果您在其他地方生成了其他子进程,waitall 将等待所有这些子进程。要仅等待您在此处生成的集合,请将上面的 Process.waitall 替换为循环 wait

pids.delete(wait) until pids.empty?

【讨论】:

  • 谢谢!但是我收到以下错误:'spawn': Exec format error - program1.rb (Errno::ENOEXEC)
  • @walterfaye 显然您的 ruby​​ 程序未标记为可执行文件。将 spawn(foo) 命令更改为 spawn('ruby', foo) 或使您的 ruby​​ 程序可执行。
【解决方案2】:

如果您想让进程在 Ruby 中并行运行,您需要研究线程,或者比使用 system 更复杂的东西。

你没有说你在什么操作系统上运行,但你为什么不使用 shell 脚本来做呢?它是内置的,非常简单:

#!/bin/sh

ruby program1.rb &
sleep 60
ruby program2.rb &
sleep 60
ruby program3.rb &
sleep 60
ruby program4.rb &

& 在 Linux 和 Mac OS 上将命令置于后台,因此脚本将立即重新获得控制权并休眠 60 秒。

除非您正在等待所有程序都完成,否则说“程序已完成运行”是没有意义的,这需要更多的工作。

【讨论】:

  • 我在 Windows 7 上。我需要等待它们全部完成,因为它们都将结果输出到一个文件,然后我通过电子邮件发送给自己。
  • 如果您正在写入文件,并且需要按作业顺序输出并按作业分组,那么您需要做的不仅仅是线程运行、并行运行或后台运行。独立运行的作业可以在不同的时间输出。如果他们都试图写入同一个文件,则输出将在所有作业之间交织。相反,您可以让它们写入自己的输出文件,然后按照您期望的顺序将它们连接到一个文件中,然后发送。
【解决方案3】:

我想你想要Process.spawn。如果您想在生成终止状态后获得有关终止状态的信息,请使用Process.waitHere's the relevant documentation; probably worth a read to figure out exactly what you want to do.

【讨论】:

    【解决方案4】:

    您可以为此使用Thread 类。特别是 .new 和 #join。 (http://www.ruby-doc.org/core-2.0/Thread.html)

    例子:

    runner.rb

    threads = [1, 2, 3, 4].map do |time|
      Thread.new { system("ruby sleep.rb #{time}") }
    end
    
    threads.map(&:join)
    
    puts "Everything done!"
    

    sleep.rb

    sleep ARGV[0].to_i
    

    输出

    > time ruby runner.rb
    Everything done!
    ruby runner.rb  0.24s user 0.05s system 7% cpu 4.125 total
    

    【讨论】:

      猜你喜欢
      • 2016-03-07
      • 2013-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-17
      • 2017-02-05
      相关资源
      最近更新 更多