bash脚本中的多线程/分叉


9

我写了一个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."

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

由于$inFile3500+行长,因此脚本需要6-7个小时才能完全执行。为了减少此时间,我计划在此脚本中使用多线程或分叉。如果我创建8个子进程,$inFile则将同时处理其中的8行。

如何才能做到这一点?


注意:不同的脚本将需要写入不同的输出文件。同样,您编写的脚本会删除输入文件,这是第一个动作!
pjc50

Answers:


10

GNUparallel就是为这种事情而制作的。您可以一次运行多次脚本,并通过管道输入不同的数据:

cat input.txt | parallel --pipe your-script.sh

默认情况下,它将根据系统上的处理器数量生成进程,但是您可以使用进行自定义-j N

一个特别巧妙的技巧是shebang包装功能。如果将Bash脚本的第一行更改为:

#!/usr/bin/parallel --shebang-wrap --pipe /bin/bash

并将其输入标准输入,然后所有这些都会自动发生。当您必须在末尾运行清理代码时,此功能不太有用。

有几件事要注意。一种是它将输入分割成连续的块,然后一次使用这些块-它不会交错行。另一个是将这些块按大小拆分,而不考虑有多少记录。您可以--block N用来设置不同的块大小(以字节为单位)。在您的情况下,大约不超过文件大小的八分之一是正确的。您的文件听起来可能太小,以至于无法全部存储在一个块中,否则将无法达到目的。

对于特定的不同用例,有很多选项,但是本教程涵盖了相当多的内容。您可能也有兴趣的选项包括--round-robin--group


1
你测试了那帮线吗?带有多个参数的Shebang不可移植。在Linux #!a b c上将导致["b c"],而在其他一些系统上将导致["b", "c"]
nyuszika7h 2014年

1
以这种方式使用时,它会重新解析自己的参数(否则,该选项就不会使用太多)。
2014年

我需要使用@MichaelHomer GNU parallel抓取HTML页面。能否请您通过这个线程unix.stackexchange.com/questions/277609/...
Swatesh Pakhare
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.