【问题标题】:How to parallelise a while loop in bash?如何在bash中并行化while循环?
【发布时间】:2017-10-06 09:21:23
【问题描述】:

我有以下并行运行的while 循环。 (logProcess 是我在脚本前面定义的函数。)

while read LINE; do
    logProcess $LINE &
done <<< "$ELS_LOGS"
wait

我需要找到一种方法来限制正在运行的进程数量。我知道有并行进程正在运行。如何转换循环以使用该命令?

【问题讨论】:

  • 可能在循环内部,您可以检查 ps -ef 和 grep log 进程并检查行数 [wc -l] 。如果这超过了您要运行的进程数,您可以休眠一段时间,直到其中一个进程完成,然后再次启动新的 logProcess。这是必需的吗?
  • logProcess $LINE,不是logProcess "$LINE"?请记住,如果您有一行包含 *,您将在命令行中获得一个文件名列表。

标签: bash parallel-processing


【解决方案1】:

我可以向您推荐 GNU Parallel。您的整个脚本将变为:

parallel -a "$ELS_LOGS" logProcess

如果logProcess 是在您的脚本中定义的函数,您需要先将其导出,然后再运行GNU Parallel,如下所示:

export -f logProcess

然后,如果您想一次运行 8 个,您只需这样做:

parallel -j 8 -a "$ELS_LOGS" logProcess

如果你想看看它会做什么,而不实际做任何事情:

parallel --dry-run ...

如果您想要进度条或 ETA:

parallel --eta ...
parallel --bar ...

【讨论】:

  • 脚本包含的功能较多,无法如上运行。理想情况下,我只需要并行化循环部分。
  • 不确定我是否理解 - 我的建议与您要求的相同。你的问题不能代表你想要的吗?
  • @MatthewBullock,如果你的函数调用其他函数,也导出那些其他函数。相比之下,如果您的函数需要修改全局、共享状态,那么您有一项在 shell 中无法完成的工作(不使用磁盘或其他外部存储进行协调):Shell 不支持线程(您有多行执行共享相同的变量状态);相反,all 它的选项是多处理风格的,其中每个子进程都有自己的变量、工作目录等。
【解决方案2】:

GNU xargs 也是完成这项工作的合适工具:

xargs -P 20 -d $'\n' -n 1 logProcess

...将运行多达 20 个并发 logProcess 实例,将给 xargs 的标准输入的每一行传递给不同的此类实例。

【讨论】:

    猜你喜欢
    • 2021-08-24
    • 2016-07-23
    • 2022-01-23
    • 1970-01-01
    • 2018-02-01
    • 2021-10-18
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    相关资源
    最近更新 更多