在没有对代码进行实质性更改的情况下,在脚本遍历(每一行)中伪造并行化



我是GNU Parallel的新手,如果您指出一些错误和误解,我会很高兴。我读了手册,但它基本上说的是一个阶段的操作,其中有必要在语法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并行之外的其他工具来实现?任何帮助都是有用的。它是理想的,例如,如果有的话。如果所有的代码都是并行的,那么很可能会产生问题。这在循环的时刻是必要的。

谢谢

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个进程。要对并发进程的数量进行一些控制,您可以使用parallel工具来代替循环:

#!/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

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

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

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

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

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

cat file | parallel inner.csh

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

awk ... | parallel ...

考虑通读教程。您的命令行将会喜欢它:https://www.gnu.org/software/parallel/parallel_tutorial.html

最新更新