bash 脚本中的多线程/分叉

Man*_*nde 9 shell-script multithreading parallelism

我编写了一个 bash 脚本,格式如下:

#!/bin/bash
start=$(date +%s)
inFile="input.txt"
outFile="output.csv"

rm -f $inFile $outFile

while read line
do

    -- Block of Commands

done < "$inFile"

end=$(date +%s)

runtime=$((end-start))

echo "Program has finished execution in $runtime seconds."
Run Code Online (Sandbox Code Playgroud)

while循环将从读取$inFile,上线执行一些活动和转储结果$outFile

由于$inFile有 3500 多行长,脚本完全执行需要 6-7 个小时。为了尽量减少这个时间,我计划在这个脚本中使用多线程或分叉。如果我创建 8 个子进程,$inFile将同时处理 8 行。

如何才能做到这一点?

Mic*_*mer 10

GNUparallel就是为这种事情而生的。您可以一次多次运行您的脚本,并为每个脚本输入不同的数据:

cat input.txt | parallel --pipe your-script.sh
Run Code Online (Sandbox Code Playgroud)

默认情况下,它会根据您系统上的处理器数量生成进程,但您可以使用-j N.

一个特别巧妙的技巧是shebang-wrapping 特性。如果您将 Bash 脚本的第一行更改为:

#!/usr/bin/parallel --shebang-wrap --pipe /bin/bash
Run Code Online (Sandbox Code Playgroud)

并在标准输入上提供数据,然后这一切都会自动发生。当您有必须在最后运行的清理代码时,这不太有用,您可能会这样做。

有几件事需要注意。一是它将您的输入分成连续的块并一次使用这些块 - 它不会交错行。另一个是这些块是按大小分割的,而不考虑有多少记录。您可以使用--block N以字节为单位设置不同的块大小。在您的情况下,文件大小不超过八分之一应该是正确的。您的文件听起来可能足够小,否则可能会在一个块中全部结束,这将违背目的。

对于特定的不同用例,有很多选项,但本教程很好地涵盖了这些内容。您可能还感兴趣的选项包括--round-robin--group