I have a program called main.rb which I would like to do the following:
我有一个叫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"
Is there a way to do the above without having program2 wait until program1 is finished and so forth? I'm thinking it might have to open a new CLI with each program? Also, I'd like to output the "Programs are done running" message only when all 4 are completed. Is there a way to do that? Thank you!
是否有一种方法可以在没有program2的情况下完成上述操作,直到program1完成等等?我想它可能需要为每个程序打开一个新的CLI ?另外,我希望在所有4条都完成时输出“程序已完成运行”消息。有办法吗?谢谢你!
4 个解决方案
#1
6
It seems you want each program to run concurrently, but wish to wait 60 seconds between launching each subprogram, then wait for all to complete. Process::spawn
is essentially system
but backgrounds the subprocess returning its pid. This should get you what you want:
看起来您希望每个程序同时运行,但是希望在启动每个子程序之间等待60秒,然后等待所有程序完成。过程::衍生本质上是系统,但背景的子进程返回它的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!'
If elsewhere you have spawned other child processes, waitall
will wait for all of them. To only wait for the set you spawned here, replace Process.waitall
above with looping over wait
如果您在其他地方生成了其他子进程,waitall将等待所有子进程。要只等待这里衍生的集合,请替换进程。在上面以循环的方式等待
pids.delete(wait) until pids.empty?
#2
3
You can use Thread
class for this. Specifically .new and #join. (http://www.ruby-doc.org/core-2.0/Thread.html)
您可以为此使用线程类。具体格式和#加入。(http://www.ruby - doc.org/core 2.0 - / - thread.html)
Example:
例子:
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
output
> time ruby runner.rb
Everything done!
ruby runner.rb 0.24s user 0.05s system 7% cpu 4.125 total
#3
1
I think you want Process.spawn
. If you want info on the termination status after you've spawned it, you use Process.wait
. Here's the relevant documentation; probably worth a read to figure out exactly what you want to do.
我想你想要程序,衍生。如果您想要在生成终止状态之后的信息,您可以使用Process.wait。这是相关文档;也许值得一读,看看你到底想做什么。
#4
1
If you want to have the processes run in parallel in Ruby, you'll need to investigate threads, or something more complex than using system
.
如果您想让进程在Ruby中并行运行,您需要研究线程,或者比使用系统更复杂的东西。
You don't say what OS you're running on, but why don't you do this with a shell script? It's built-in and very easy:
你没有说你在运行什么操作系统,但是为什么不使用shell脚本呢?它是内置的,非常简单:
#!/bin/sh
ruby program1.rb &
sleep 60
ruby program2.rb &
sleep 60
ruby program3.rb &
sleep 60
ruby program4.rb &
&
puts a command into the background on Linux and Mac OS, so the script will immediately regain control and sleeps 60 seconds.
将一个命令放到Linux和Mac OS的后台,这样脚本就会立即重新获得控制,并休眠60秒。
It doesn't make sense to say "Programs are done running" unless you're waiting for all of them to finish, which takes a bit more work.
说“程序已经运行完毕”是没有意义的,除非您等待所有的程序都完成,这需要更多的工作。
#1
6
It seems you want each program to run concurrently, but wish to wait 60 seconds between launching each subprogram, then wait for all to complete. Process::spawn
is essentially system
but backgrounds the subprocess returning its pid. This should get you what you want:
看起来您希望每个程序同时运行,但是希望在启动每个子程序之间等待60秒,然后等待所有程序完成。过程::衍生本质上是系统,但背景的子进程返回它的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!'
If elsewhere you have spawned other child processes, waitall
will wait for all of them. To only wait for the set you spawned here, replace Process.waitall
above with looping over wait
如果您在其他地方生成了其他子进程,waitall将等待所有子进程。要只等待这里衍生的集合,请替换进程。在上面以循环的方式等待
pids.delete(wait) until pids.empty?
#2
3
You can use Thread
class for this. Specifically .new and #join. (http://www.ruby-doc.org/core-2.0/Thread.html)
您可以为此使用线程类。具体格式和#加入。(http://www.ruby - doc.org/core 2.0 - / - thread.html)
Example:
例子:
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
output
> time ruby runner.rb
Everything done!
ruby runner.rb 0.24s user 0.05s system 7% cpu 4.125 total
#3
1
I think you want Process.spawn
. If you want info on the termination status after you've spawned it, you use Process.wait
. Here's the relevant documentation; probably worth a read to figure out exactly what you want to do.
我想你想要程序,衍生。如果您想要在生成终止状态之后的信息,您可以使用Process.wait。这是相关文档;也许值得一读,看看你到底想做什么。
#4
1
If you want to have the processes run in parallel in Ruby, you'll need to investigate threads, or something more complex than using system
.
如果您想让进程在Ruby中并行运行,您需要研究线程,或者比使用系统更复杂的东西。
You don't say what OS you're running on, but why don't you do this with a shell script? It's built-in and very easy:
你没有说你在运行什么操作系统,但是为什么不使用shell脚本呢?它是内置的,非常简单:
#!/bin/sh
ruby program1.rb &
sleep 60
ruby program2.rb &
sleep 60
ruby program3.rb &
sleep 60
ruby program4.rb &
&
puts a command into the background on Linux and Mac OS, so the script will immediately regain control and sleeps 60 seconds.
将一个命令放到Linux和Mac OS的后台,这样脚本就会立即重新获得控制,并休眠60秒。
It doesn't make sense to say "Programs are done running" unless you're waiting for all of them to finish, which takes a bit more work.
说“程序已经运行完毕”是没有意义的,除非您等待所有的程序都完成,这需要更多的工作。