我有一个批处理脚本,它从几个qsub作业开始,我想在它们全部完成后陷阱。
我不想使用-sync选项,因为我希望它们同时运行。每个作业都有一组不同的命令行参数。
我希望我的脚本等到所有工作完成后再做一些事情。我不想使用睡眠功能,例如检查某些文件是否在每30秒后生成一次,因为这会消耗资源。
我相信Torque可能有一些选择,但我正在运行SGE。
关于如何实现这一点的任何想法?
由于 附: 我找到了另一个帖子 Link
有一个回应
您可以使用wait来停止执行,直到完成所有工作。您甚至可以收集所有退出状态和其他运行统计信息(花费的时间,当时完成的工作数,无论如何),如果您循环等待特定ID。
但我不知道如何在不轮询某些价值的情况下使用它。可以使用bash陷阱,但我如何使用qsub?
答案 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.py
和log.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 jid
或qsub -hold_jid jobname
保留该数组为止。