等待一组qsub作业完成

时间:2012-07-17 14:52:11

标签: qsub

我有一个批处理脚本,它从几个qsub作业开始,我想在它们全部完成后陷阱。

我不想使用-sync选项,因为我希望它们同时运行。每个作业都有一组不同的命令行参数。

我希望我的脚本等到所有工作完成后再做一些事情。我不想使用睡眠功能,例如检查某些文件是否在每30秒后生成一次,因为这会消耗资源。

我相信Torque可能有一些选择,但我正在运行SGE。

关于如何实现这一点的任何想法?

由于 附: 我找到了另一个帖子 Link

有一个回应

您可以使用wait来停止执行,直到完成所有工作。您甚至可以收集所有退出状态和其他运行统计信息(花费的时间,当时完成的工作数,无论如何),如果您循环等待特定ID。

但我不知道如何在不轮询某些价值的情况下使用它。可以使用bash陷阱,但我如何使用qsub?

9 个答案:

答案 0 :(得分:34)

启动qsub作业,使用-N选项为其指定任意名称(job1,job2等):

qsub -N job1 -cwd ./job1_script
qsub -N job2 -cwd ./job2_script
qsub -N job3 -cwd ./job3_script

启动您的脚本并告诉它等到名为job1,job2和job3的作业在启动之前完成:

qsub -hold_jid job1,job2,job3 -cwd ./results_script

答案 1 :(得分:3)

qsub -hold_jid job1,job2,job3 -cwd ./myscript

答案 2 :(得分:3)

另一种选择(来自here)如下:

FIRST=$(qsub job1.pbs)
echo $FIRST
SECOND=$(qsub -W depend=afterany:$FIRST job2.pbs)
echo $SECOND
THIRD=$(qsub -W depend=afterany:$SECOND job3.pbs)
echo $THIRD

洞察力是qsub返回jobid,这通常被转储到标准输出。相反,在变量($FIRST$SECOND$THIRD)中捕获它,并在排队作业时使用-W depend=afterany:[JOBIDs]标志来控制它们何时出列的依赖关系结构

答案 3 :(得分:2)

这适用于bash,但这些想法应该是可移植的。使用-terse可以帮助构建一个带有作业ID的字符串来等待;然后提交一个假工作,使用-hold_jid等待以前的工作和-sync y,以便qsub不会返回,直到它(因此所有先决条件)都已完成:

# example where each of three jobs just sleeps for some time:
job_ids=$(qsub -terse -b y sleep 10)
job_ids=job_ids,$(qsub -terse -b y sleep 20)
job_ids=job_ids,$(qsub -terse -b y sleep 30)
qsub -hold_jid ${job_ids} -sync y -b y echo "DONE"  
  • -terse选项使qsub的输出只是作业ID
  • -hold_jid选项(如其他答案中所述)使作业等待指定的作业ID
  • -sync y选项(由OP引用)要求qsub在提交的作业完成之前不返回
  • -b y指定该命令不是脚本文件的路径(例如,我使用sleep 30作为命令)

有关详细信息,请参阅man page

答案 4 :(得分:2)

如果所有作业在名称中都有共同模式,则可以在提交作业时提供该模式。 https://linux.die.net/man/1/sge_types显示了您可以使用的模式。例如:

-hold_jid "job_name_pattern*"

答案 5 :(得分:1)

如果你想要处理150个文件并且每次只能运行15个文件,而另一个文件在队列中,你可以设置这样的东西。

# split my list files in a junk of small list having 10 file each
awk 'NR%10==1 {x="F"++i;}{ print >  "list_part"x".txt" }'  list.txt

qsub所有的工作,每个list_part * .txt的第一个保持第二个....第二个保持第三个......依此类推。

for list in $( ls list_part*.txt ) ; do
    PREV_JOB=$(qsub start.sh) # create a dummy script start.sh just for starting
 for file in  $(cat $list )  ; do
   NEXT_JOB=$(qsub -v file=$file  -W depend=afterany:$PREV_JOB  myscript.sh )
   PREV_JOB=$NEXT_JOB
 done
done

如果你在myscript.sh中有一个需要移动或下载许多文件或在集群中创建密集流量的过程,这很有用

答案 6 :(得分:0)

我需要更多的灵活性,因此我为此目的here构建了一个Python模块。您可以直接将模块作为脚本(python qsub.py)运行以进行演示。

用法:

$ git clone https://github.com/stevekm/util.git
$ cd util
$ python
Python 2.7.3 (default, Mar 29 2013, 16:50:34)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import qsub
>>> job = qsub.submit(command = 'echo foo; sleep 60', print_verbose = True)
qsub command is:

qsub -j y -N "python" -o :"/home/util/" -e :"/home/util/" <<E0F
set -x
echo foo; sleep 60
set +x
E0F

>>> qsub.monitor_jobs(jobs = [job], print_verbose = True)
Monitoring jobs for completion. Number of jobs in queue: 1
Number of jobs in queue: 0
No jobs remaining in the job queue
([Job(id = 4112505, name = python, log_dir = None)], [])

使用Python 2.7和SGE设计,因为我们的系统运行。所需的唯一非标准Python库包括tools.pylog.py模块,以及sh.py(也包括在内)

如果您希望完全保留在bash中,显然没有帮助,但如果您需要等待qsub个工作,那么我会想象您的工作流程正朝着可能因使用Python而受益的复杂性代替。

答案 7 :(得分:0)

#!/depot/Python-2.4.2/bin/python

import os
import subprocess
import shlex

def trackJobs(jobs, waittime=4):
    while len(jobs) != 0:
        for jobid in jobs:
            x = subprocess.Popen(['qstat', '-j', jobid], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            std_out, std_err = x.communicate()
            if std_err :
                jobs.remove(jobid)
                break
        os.system("sleep " + str(waittime))
    return

这是简单的代码,您可以在其中跟踪qsub作业的完成状态。 这里的函数接受jobId列表(例如['84210770','84210774','84210776','84210777','84210778'])

答案 8 :(得分:0)

您可以启动作业阵列qsub -N jobname -t 1-"$numofjobs" -tc 20,它只有一个作业ID,一次运行20个。您给它起一个名字,直到使用qsub -hold_jid jidqsub -hold_jid jobname保留该数组为止。