linux - 即使某些进程完成,也要不断填充并行进程的四个槽

标签 linux bash shell unix process

我有一个脚本,一次运行 4 个进程的批处理,我不关心获取每个进程的返回代码。我不想同时运行超过 4 个进程。以下方法的问题是它一次最多不能填充 4 个进程。例如,如果 proc2 和 proc3 提前完成,我希望 proc 5 和 6 启动,而不是仅在 1-4 完成后启动。我怎样才能在 bash 中实现这一点?

run_func_1 &
run_func_2 &
run_func_3 &
run_func_4 &
wait
run_func_5 &
run_func_6 &
run_func_7 &
run_func_8 &
wait

最佳答案

我尝试使用工作人员池和作业队列进行自定义实现。 一旦前一个工作完成,新工作人员就会从队列中获取工作。

您可以根据需要调整此脚本,但我希望您能明白我的意图。

这是脚本:

#!/bin/bash

f1() { echo Started f1; sleep 10; echo Finished f1; }
f2() { echo Started f2; sleep 8; echo Finished f2; }
f3() { echo Started f3; sleep 12; echo Finished f3; }
f4() { echo Started f4; sleep 14; echo Finished f4; }
f5() { echo Started f5; sleep 7; echo Finished f5; }

declare -r MAX_WORKERS=2
declare -a worker_pids
declare -a jobs=('f1' 'f2' 'f3' 'f4' 'f5')

available_worker_index() {
    # If number of workers is less than MAX_WORKERS
    # We still have workers that are idle
    declare worker_count="${#worker_pids[@]}"
    if [[ $worker_count -lt $MAX_WORKERS ]]; then
        echo "$worker_count"
        return 0
    fi

    # If we reached this code it means
    # All workers are already created and executing a job
    # We should check which of them finished and return it's index as available
    declare -i index=0
    for pid in "${worker_pids[@]}"; do
        is_running=$(ps -p "$pid" > /dev/null; echo "$?")
        if [[ $is_running != 0 ]]; then
            echo "$index"
            return 0
        fi
        index+=1
    done

    echo "None"
}

for job in "${jobs[@]}"; do
    declare worker_index
    worker_index=$(available_worker_index)
    while [[ $worker_index == "None" ]]; do
        # Wait for available worker
        sleep 3
        worker_index=$(available_worker_index)
    done

    # Run the job in background
    "$job" &

    # Save it's pid for later
    pid="$!"
    worker_pids["$worker_index"]="$pid"
done

# Wait all workers to finish
wait

您只需更改 MAX_WORKERS 变量即可轻松更改工作池的大小。

关于linux - 即使某些进程完成,也要不断填充并行进程的四个槽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50171483/

相关文章:

linux - elf 文件自以为小,其实很大!无法生成 .bin 和 .hex 文件

c++ - 如何在 Ubuntu 中构建 OpenSMILE?

linux - 在 Linux 中移动文件夹

php - cpanel/whm如何执行linux命令

linux - 如何比较 bash 中的两个配对列表?

linux - CUPS Web 界面的工作原理

linux - 检查目录中是否存在大量 .gz 文件的命令

linux - awk从列中找到最大值和最小值并存储在其他列中

linux - 收集文件名的 bash 脚本似乎被空格弄糊涂了

ruby - 交互式 Ruby 子 shell 有什么意义?