如何使用xargs并行执行数千个命令?

3

我目前通过循环在qsub上排队了一堆工作

for fn in $FNS; do
    queue_job $(options_a $fn) $(options_b $fn)
done

queue_job 是一个通过使用 qsub 排队作业的脚本,并且 options_a/b 是我编写的基于文件名添加一些作业选项的函数。我通过这种方式排队多达 5k 个作业,我希望能够立即将它们全部添加到队列中(或者以更大的块如每次 40 个)而不是在循环中逐个添加。

我知道我可以将行发送到xargs并以并行方式执行它们。

??? | xargs -P 40 -I{} command {}

但我不确定如何将我的for循环翻译成xargs


2
有趣。为了更好地帮助我们理解您的问题,请编辑您的问题并包含4-5行队列作业文件中的内容(它是一个文件,对吧?(或者可以用测试文件替代?))。祝你好运。 - shellter
1
只需将以下内容翻译为中文即可:xargs .. sh -c 'fn=$1; queue_job $(options_a $fn) $(options_b $fn)' -- - KamilCuk
你使用哪个引擎(SGE?) - dash-o
3个回答

2
qsub接口只允许一次提交一个作业,不能进行批量提交,这将限制并行提交作业的优势(通常作业提交很快)。
对于特定情况,有两个(bash)函数(即options_aoptions_b),它们将根据文件名扩展为特定作业参数。这可能会限制根据评论建议使用xargs直接执行的方式-这些函数不太可能在路径中可用。
选项:
创建一个包装器来源(或包括)这些函数的queue_job。从xargs使用这个包装器。
xargs -P40 -I{} queue_job_x1 '{}'

queue_job_x1

#! /bin/bash
function options_a {
   ...
}

function option_b {
   ...
}

queue_job $(options_a $fn) $(options_b $fn)'

将相关函数放入.sh文件中可能是个好主意,这样多个脚本可以调用。


0

使用GNU Parallel,代码如下:

export -f options_a
export -f options_b

parallel -j40 'queue_job $(options_a {}) $(options_b {})' ::: $FNS

0

xargs 不需要。

如果你将任务放到后台,下一个任务可以立即开始。你可以在脚本中添加一些智能功能,使其限制同时执行的任务数量。例如:

COUNT=1
LIMIT=40
for fn in $FNS; do
    queue_job $(options_a $fn) $(options_b $fn) &
    if [ $COUNT -lt $LIMIT ] ; then
        COUNT=$[COUNT+1]
        continue
    fi
    wait -n
done
wait

queue_job 命令被放置在后台。如果 COUNT 达到了 LIMIT,则 if 体将继续生成并行的 queue_job 任务。如果 COUNT 达到了 LIMIT,则循环会等待其中一个正在运行的任务完成,然后再生成下一个任务。最后的 wait 让脚本一直阻塞,直到所有任务都完成。

我通过模拟带有 2 秒睡眠、30 个任务和限制为 10 个并行任务的 queue_job 进行了测试。正如预期的那样,模拟在大约 6 秒后完成。

在线试用!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接