【问题标题】:Limit number of parallel jobs in bash [duplicate]限制bash中的并行作业数量[重复]
【发布时间】:2021-08-11 18:09:35
【问题描述】:

我想从通过参数传递的文件中读取链接,并从每个链接下载内容。 如何与 20 个进程并行执行? 我了解如何使用无限数量的进程来做到这一点:

#!/bin/bash

filename="$1"
mkdir -p saved

while read -r line; do
    url="$line"
    name_download_file_sha="$(echo $url | sha256sum | awk '{print $1}').jpeg"
    curl -L $url > saved/$name_download_file_sha &

done < "$filename"
wait

【问题讨论】:

  • shell 根本不暴露线程。您可以轻松地使用并行进程,方法是使用&amp; 将每个作业作为后台,就像您在此处所做的那样。您显然实际上是在问如何限制并发进程的数量。我已经相应地更新了您的问题。
  • 问题和代码不匹配。究竟是什么问题?每个 curl 命令都在后台运行,因此是并行的。您想读取 20 个文件而不是 1 个文件?或者你想运行 20 curl(但是为什么?)

标签: linux bash parallel-processing


【解决方案1】:

你可以添加这个测试:

    until [ "$( jobs -lr 2>&1 | wc -l)"  -lt 20 ]; do
        sleep 1
    done

这将保持最多 21 个并行 curl 实例。 等到你达到 19 或更低的值再开始另一个。

如果你使用 GNU sleep ,你可以做 sleep 0.5 ,以优化等待时间

所以你的代码将是

#!/bin/bash

filename="$1"
mkdir -p saved

while read -r line; do
    until [ "$( jobs -lr 2>&1 | wc -l)"  -lt 20 ]; do
        sleep 1
    done
    url="$line"
    name_download_file_sha="$(echo $url | sha256sum | awk '{print $1}').jpeg"
    curl -L $url > saved/$name_download_file_sha &

done < "$filename"
wait

【讨论】:

  • 由于睡眠,这个并行化的脚本可能(尽管不太可能)花费比顺序运行所有作业更长的时间。您可以将until 替换为if 并改用wait -n
  • @Socowi 我会看看你的建议
【解决方案2】:

xargs -P 是简单的解决方案。当你想保存到单独的文件时,它会变得有点复杂,但你可以使用sh -c 来添加这个位。

: ${processes:=20}
< $filename xargs -P $processes -I% sh -c '
    line="$1"
    url_file="$line"
    name_download_file_sha="$(echo $url_file | sha256sum | awk "{print \$1}").jpeg"
    curl -L $url > saved/$name_download_file_sha 
' -- %

根据 Triplee 的建议,我已将环境变量小写并将其名称更改为“进程”以更正确。

我还对 awk 脚本进行了建议的更正以避免引用问题。

您可能仍会发现将 awk 脚本替换为 cut -f1 会更容易,但如果是空格(而不是制表符),则需要指定剪切分隔符。

【讨论】:

  • 您可以轻松地切换到 awk 脚本周围的双引号;只需反斜杠转义任何反斜杠、双引号、(反引号)和美元符号。
  • 那些是进程,而不是线程。可能避免使用大写的私有变量;另见stackoverflow.com/questions/673055/…
  • @tripleee:采纳了你的建议。
猜你喜欢
  • 2010-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-26
相关资源
最近更新 更多