脚本循环(foreach 行)中的假并行化,而无需对代码进行实质性更改
Fake parallelization in script over loop (foreach line) without substantial changes in code
我是 GNU Parallel 的新手,如果您指出一些错误和误解,我将很高兴。我阅读了手册,但它基本上说的是单阶段操作,其中有必要在语法 GNU Parallel(解包、移动等)中指定 "action" 的定义,并且没有指定多阶段步骤当您需要在不更改(显着)代码的情况下执行一些操作时(如果课程完全可能)
是否可以在不支持的代码中"fake"并行处理?
该代码有一个循环(包含任何格式的文件列表,并且在某些时候它会循环)并且您需要该代码同时而不是顺序地对所有文件执行某些操作(无论是哪种操作) (无需实质性更改代码或仅更改大约 138 行 - 见下文)。就是那种不需要拆分文件之类的并行处理,而是一次处理所有文件。
例如:这里是感兴趣的部分代码,完整代码在这里 - 138 行 GMT
# <code> actions (see full code - link below) and check input file availability
#loop
#
foreach line (`awk '{print [=10=]}' `)
# <code> actions (see full code - link below)
end if
来源,完整代码:GMT
也许除了GNU Parallel 之外,还可以使用其他工具来实现?任何帮助都是有用的。例如,如果有的话,这是可取的。如果你让所有的代码并行,它可能会导致问题。在循环的那一刻是必要的。
谢谢
csh 有很多限制;缺乏功能是其中之一,任何超过几行的脚本都会很快变成一团糟。这是通常不鼓励在 csh 中编写脚本的一个重要原因。
话虽这么说,修改它的最简单方法是将循环体提取到一个单独的脚本中,并在附加 &
的情况下调用它。例如:
main.csh
:
#!/bin/csh
foreach line (`awk '{print [=10=]}' `)
./loop.csh "$line" &
end
loop.csh
:
#!/bin/csh
set line = ""
echo "=> $line"
sleep 5
您可能需要添加更多参数,而不仅仅是 $line
;我没有检查整个脚本。
&
将使 shell 继续而不等待命令完成。因此,如果有 5,000 行,您将同时 运行 5,000 个进程。要对并发进程的数量进行一些控制,您可以使用并行工具而不是循环:
#!/bin/csh
awk '{print [=12=]}' | 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
使用变量,则 setenv
它们在 运行 之前 parallel
:
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
我是 GNU Parallel 的新手,如果您指出一些错误和误解,我将很高兴。我阅读了手册,但它基本上说的是单阶段操作,其中有必要在语法 GNU Parallel(解包、移动等)中指定 "action" 的定义,并且没有指定多阶段步骤当您需要在不更改(显着)代码的情况下执行一些操作时(如果课程完全可能)
是否可以在不支持的代码中"fake"并行处理? 该代码有一个循环(包含任何格式的文件列表,并且在某些时候它会循环)并且您需要该代码同时而不是顺序地对所有文件执行某些操作(无论是哪种操作) (无需实质性更改代码或仅更改大约 138 行 - 见下文)。就是那种不需要拆分文件之类的并行处理,而是一次处理所有文件。
例如:这里是感兴趣的部分代码,完整代码在这里 - 138 行 GMT
# <code> actions (see full code - link below) and check input file availability
#loop
#
foreach line (`awk '{print [=10=]}' `)
# <code> actions (see full code - link below)
end if
来源,完整代码:GMT
也许除了GNU Parallel 之外,还可以使用其他工具来实现?任何帮助都是有用的。例如,如果有的话,这是可取的。如果你让所有的代码并行,它可能会导致问题。在循环的那一刻是必要的。
谢谢
csh 有很多限制;缺乏功能是其中之一,任何超过几行的脚本都会很快变成一团糟。这是通常不鼓励在 csh 中编写脚本的一个重要原因。
话虽这么说,修改它的最简单方法是将循环体提取到一个单独的脚本中,并在附加 &
的情况下调用它。例如:
main.csh
:
#!/bin/csh
foreach line (`awk '{print [=10=]}' `)
./loop.csh "$line" &
end
loop.csh
:
#!/bin/csh
set line = ""
echo "=> $line"
sleep 5
您可能需要添加更多参数,而不仅仅是 $line
;我没有检查整个脚本。
&
将使 shell 继续而不等待命令完成。因此,如果有 5,000 行,您将同时 运行 5,000 个进程。要对并发进程的数量进行一些控制,您可以使用并行工具而不是循环:
#!/bin/csh
awk '{print [=12=]}' | 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
使用变量,则 setenv
它们在 运行 之前 parallel
:
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