如何运行5个Shell作业同时在队列中保持休息?

时间:2018-01-29 09:19:31

标签: multithreading shell unix ksh

虽然“任务假脱机程序”和“at”都处理多个队列并允许稍后执行命令,但是at项目通过将结果通过电子邮件发送给排队命令的用户来处理命令的输出,而Task Spooler允许您可以从命令行获取结果。

但是我正在寻找的方法是允许我同时运行5个作业并将其余的作业保留在队列中,所以当5个中的任何一个结束时它将启动下一个作业。

因此,如果5个作业在其中任何作业完成后再运行4个,则下一个作业将开始执行,并且5个作业将同时运行。

有办法处理这样的任务吗?

3 个答案:

答案 0 :(得分:1)

当然,这取决于您希望如何开始任务。但我们假设它们是基于循环的。以下内容将在后台启动所有N命令。

#!/usr/bin/env bash

for i in {1..N}; do
   # do awesome command based on $i
   command $i &
done
wait

因此,如果您只想启动5个作业,则需要跟踪正在运行的内容:

#!/usr/bin/env bash

Njobs=5

for i in {1..N}; do
   # Checks how many jobs are currently running
   while [[ $(jobs -p | wc -l) > $Njobs ]]; do
     sleep 0.1
   done

   # do awesome command based on $i
   command $i &
done
wait

答案 1 :(得分:1)

您已经有了一个工具:GNU Parallel

parallel --jobs 4 bash ::: script1.sh script2.sh script3.sh script4.sh

有关示例,请参阅Parallel tutorial

答案 2 :(得分:1)

如果您正在使用任务后台处理程序,则可以执行您要的操作。使用-S <number>标志指定“插槽”(并发运行的作业)的数量。您甚至可以使用-D <job id>来使不同的作业取决于另一个特定作业的完成情况。

因此,在您的示例中,如果设置tsp -S 5,则任务假脱机程序将运行前5个作业,并将下一个4排队。一旦原始5个作业中的一个完成,则下一个排队的作业(基于最低作业ID)将开始。随着正在运行的作业完成并打开更多的插槽,这种情况将继续发生。

也请注意,在Ubuntu(以及其他基于Debian的其他系统)上,任何其他阅读此文档的人都可以将任务假脱机程序称为tsp,以免与openssl-ts工具冲突。在大多数其他系统上,它应仅称为ts。这就是为什么即使在Ubuntu上,任务假脱机程序也将自己称为ts

关于手册,关于插槽:

MULTI-SLOT
       ts by default offers a queue where each job runs only after the previous finished.  Nevertheless, you can  change  the
       maximum  number  of jobs running at once with the -S [num] parameter. We call that number the amount of slots. You can
       also set the initial number of jobs with the environment variable TS_SLOTS .  When  increasing  this  setting,  queued
       waiting  jobs  will  be run at once until reaching the maximum set. When decreasing this setting, no other job will be
       run until it can meet the amount of running jobs set.   When using an amount of slots greater than 1,  the  action  of
       some  commands may change a bit. For example, -t without jobid will tail the first job running, and -d will try to set
       the dependency with the last job added.

       -S [num]
              Set the maximum amount of running jobs at once. If you don't specify num it will return the maximum  amount  of
              running jobs set.