You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何并行运行Shell函数的多个实例并等待全部执行完成?

问题

我有如下Shell脚本:

#!/bin/bash
myfunc() {
    #do something (call a rest service)
    sleep 300
    status=$(get status of the operation performed above)
    while [ "$status" != "succeeded" ]; do
        #do something (call a rest service)
        sleep 300
        status=$(get status of the operation performed above)
    done
}
a=0
while [ $a -lt 1000 ]
do
    a=`expr $a + 1`
    myfunc
done

在最优情况下,上述脚本至少需要5×1000=5000秒才能执行完成。请问是否有办法让myfunc的调用并行化,使while循环可以生成多个myfunc的运行实例?

注意:脚本必须等待所有myfunc实例执行完成后再结束。


解决方案

当然可以!在bash里实现并行化最直接的方式就是把每个myfunc的调用放到后台运行(用&符号),然后用wait命令等待所有后台进程完成。这样所有myfunc实例会同时启动,总耗时就接近单个myfunc的执行时间(最优下5分钟),而不是串行的5000秒。

基础并行实现版本

修改你的脚本,把myfunc调用改成后台运行,同时记录进程ID,最后统一等待:

#!/bin/bash
myfunc() {
    #do something (call a rest service)
    sleep 300
    status=$(get status of the operation performed above)
    while [ "$status" != "succeeded" ]; do
        #do something (call a rest service)
        sleep 300
        status=$(get status of the operation performed above)
    done
}

# 存储后台进程ID的数组
pids=()

a=0
while [ $a -lt 1000 ]
do
    a=$((a + 1))  # 用更现代的bash算术写法替代expr
    myfunc &  # 让myfunc在后台运行
    pids+=($!)  # 记录当前后台进程的ID
done

# 等待所有后台进程执行完成
wait "${pids[@]}"

echo "所有myfunc实例已执行完成!"

进阶:控制并发数(避免资源耗尽)

一次性启动1000个并发进程可能会消耗大量系统资源(比如网络连接、进程数),如果你的REST服务有并发限制,或者系统资源有限,建议控制同时运行的进程数,比如每次只启动20个,等一批完成再启动下一批:

#!/bin/bash
myfunc() {
    #do something (call a rest service)
    sleep 300
    status=$(get status of the operation performed above)
    while [ "$status" != "succeeded" ]; do
        #do something (call a rest service)
        sleep 300
        status=$(get status of the operation performed above)
    done
}

max_concurrent=20  # 设置最大并发数
pids=()

a=0
while [ $a -lt 1000 ]
do
    a=$((a + 1))
    myfunc &
    pids+=($!)

    # 当进程数达到最大并发数时,等待任意一个后台进程完成再继续
    if [ ${#pids[@]} -ge $max_concurrent ]; then
        wait -n  # 等待任意一个后台进程结束
        # 移除已完成的进程ID(可选,保持数组整洁)
        pids=("${pids[@]/$!/}")
    fi
done

# 等待剩余的所有进程完成
wait "${pids[@]}"

echo "所有myfunc实例已执行完成!"

这个版本既保留了并行执行的效率,又避免了一次性启动过多进程导致的资源耗尽问题。

内容的提问来源于stack exchange,提问作者Vajira Prabuddhaka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 19:02:32