脚本循环(foreach行)中的假并行化没有实质性的代码更改

时间:2016-11-16 08:16:34

标签: loops parallel-processing csh gnu-parallel

我是GNU Parallel的新手,如果你指出一些错误和误解,我会很高兴的。我阅读了手册,但它基本上讲的是一阶段操作,其中有必要指定" action"的定义。在语法GNU Parallel(解包,移动等)中,当您需要执行一些操作而不更改(显着)代码(如果课程完全可能)时,没有指定多阶段步骤

有可能"假"在不支持它的代码中并行处理? 代码有一个循环(包含任何格式的文件列表,并且在某些时候它涉及到循环)以及所有你需要的代码来同时对所有文件执行某些操作(不管是什么类型的操作)而不是顺序(不会大幅改变代码或只改变138行 - 见下文)。它不需要那种并行处理来分割文件或类似的东西,而只是一次处理所有文件。

例如:以下是感兴趣的代码的一部分,此处为完整代码 - 138行GMT

# <code> actions (see full code - link below) and check input file availability
#loop
#
  foreach line (`awk '{print $0}' $1`)
# <code> actions (see full code - link below)
end if

来源,完整代码:GMT

也许它可以使用除GNU Parallel之外的其他工具来实现?任何帮助都很有用。例如,如果有的话,是理想的。如果你使所有代码并行,它可能会导致问题。在循环的那一刻它是必要的。

由于

2 个答案:

答案 0 :(得分:1)

csh有很多局限性;缺乏功能就是其中之一,任何超过几行的脚本都会很快变成意大利面。这是因为不鼓励在csh中编写脚本的一个重要原因。

话虽这么说,修改它的最简单方法是将循环体提取出一个单独的脚本,并在附加&的情况下调用它。例如:

main.csh

#!/bin/csh

foreach line (`awk '{print $0}' $1`)
    ./loop.csh "$line" &
end

loop.csh

#!/bin/csh

set line = "$1"
echo "=> $line"
sleep 5

您可能需要添加更多参数,而不仅仅是$line;我没有检查整个脚本。

&将使shell继续而不等待命令完成。因此,如果有5,000行,您将同时运行5,000个进程。要对同时进程的数量进行一些控制,可以使用并行工具而不是循环:

#!/bin/csh

awk '{print $0}' $1 | parallel ./loop.csh`

或者如果您想坚持使用循环,可以使用pgrep来限制同时进程的最大数量:

foreach line (a b c d e f g h i)
    set numprocs = `pgrep -c loop.csh`
    if ( $numprocs > 2 ) then
        sleep 2
        continue
    endif

    ./loop.csh "$line" &
end

答案 1 :(得分:1)

如果可以将循环的内部部分移动到脚本中:

parallel inner.csh ::: a b c d e f g h i

如果inner.csh使用变量,那么在运行setenv之前parallel使用变量:

setenv myvar myval
parallel inner.csh ::: a b c

a, b, and c将作为第一个arg传递给inner.csh。要从文件中读取参数,请使用:

cat file | parallel inner.csh

这也适用于从awk读取输出:

awk ... | parallel ...

考虑浏览教程。您的命令行会爱你:https://www.gnu.org/software/parallel/parallel_tutorial.html