linux - Bash 并发作业卡住了

标签 linux bash shell concurrency

我已经实现了一种在 bash 中进行并发作业的方法,如 here 所示.

我正在遍历一个包含大约 13000 行的文件。我只是测试和打印每一行,这样:

#!/bin/bash
max_bg_procs(){
    if [[ $# -eq 0 ]] ; then
        echo "Usage: max_bg_procs NUM_PROCS.  Will wait until the number of background (&)"
        echo "           bash processes (as determined by 'jobs -pr') falls below NUM_PROCS"
        return
    fi
    local max_number=$((0 + ${1:-0}))
    while true; do
        local current_number=$(jobs -pr | wc -l)
        if [[ $current_number -lt $max_number ]]; then
                echo "success in if"
                break
        fi
        echo "has to wait"
        sleep 4
    done
}

download_data(){
    echo "link #" $2 "["$1"]"
}

mapfile -t myArray < $1

i=1
for url in "${myArray[@]}"
do
    max_bg_procs 6
    download_data $url $i &
    ((i++))
done
echo "finito!"

我也尝试过其他解决方案,例如 thisthis ,但我的问题一直存在:

在“随机”给定步骤,通常在第 2000 次和第 5000 次迭代之间,它会卡住。我已经将那些不同的 echo 放在代码的中间,看看它会在哪里卡住,但它打印的最后一件事是 $url $i

我已经完成了简单的测试以删除任何并行性并只循环文件内容:一切正常并且循环到最后。

所以这让我觉得我在并行性上遗漏了一些限制,我想知道是否有人可以帮助我解决这个问题。

非常感谢!

最佳答案

在这里,我们有多达 6 个并行的 bash 进程调用 download_data,每个进程每次调用最多传递 16 个 URL。根据您自己的调整进行调整。

请注意,这需要 bash(用于导出函数支持)和 GNU xargs。

#!/usr/bin/env bash
#              ^^^^- not /bin/sh

download_data() {
  echo "link #$2 [$1]" # TODO: replace this with a job that actually takes some time
}
export -f download_data
<input.txt xargs -d $'\n' -P 6 -n 16 -- bash -c 'for arg; do download_data "$arg"; done' _

关于linux - Bash 并发作业卡住了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42563005/

相关文章:

linux按单词过滤php结果并写入文件

linux - 连接硬编码目录和用户创建的文本文件会在不应该的时候添加根级路径

arrays - Bash:如何将两个数组组合成第三个数组?

mysql - shell脚本问题可能是因为引号

shell - bash 读取的 POSIX 替代方案,具有超时和字符限制

linux - 设备树和平台驱动程序中的设备是如何连接的

Linux I/O 重定向

bash - 在循环中打印 sql 查询的单个数据到 stroud

shell - UNIX 排序命令如何对非常大的文件进行排序?

linux - 如何在 Linux 上制作文档集?