首页 > 解决方案 > 如何创建/管理作业队列

问题描述

我在有序列表中有数千个 shell 作业的队列,我需要从上到下并行运行 4 个作业以避免使 cpu 饱和。如果我只是将作业列表拆分为 4 个批处理脚本,那么运行时不会对齐,并且其中一个脚本将在其他脚本之前完成,还有很多工作要做。我正在寻找一种方法让所有 4 个批处理作业从队列顶部拉出下一个可用作业。

我已经在工作中尝试过 bash,但这不是我想要的

标签: bash

解决方案


我仍然喜欢自己制作这样的脚本:p 在根据 N 的大小运行命令的脚本下方。一旦进程退出,该条目将用于存储另一个子 pid。

run_from_file.sh

#! /bin/bash

N=4  # Amount of jobs to run in parallel
T=0  # Counter for amount of jobs
Q=() # Job queue
FILE='jobs.txt'

# Clean Q array
function _clean {
        for ((i=0; i < ${N}; ++i)); do
                tst=/proc/${Q[$i]}
                if [ ! -d $tst ]; then
                        Q[$i]=0
                fi
        done
}

# Setup the Q
for ((i=0; i < $N; i++)); do
        Q[$i]=0
done

while read -r line; do
        echo $line
        $line &

        # Try to find an open sport (Q[i]=0)
        while true; do
                for ((i=0; i < ${N}; ++i)); do
                        if [ ${Q[$i]} -eq 0 ]; then
                                Q[$i]=$!
                                break 2
                        fi
                done
                # Clean the Q array if no free entry is found
                _clean
        done
        ((T++))
done < ${FILE}
wait
echo "Processed ($T/$(wc -l < jobs.txt)) jobs"
exit 0

工作.txt

sleep 1s
sleep 1s
sleep 1s
sleep 1s
sleep 10s
sleep 5s
sleep 2s
sleep 2s
sleep 4s
sleep 3s
sleep 3s
sleep 3s

OLD:
我喜欢自己创造这样的东西,因为它是可扩展的。例如,它允许您在wait调用之前执行某些操作,或者您可以获取子进程 ID 并将其存储在文本文件中。

run_from_file.sh

#! /bin/bash

X=0 # Counter 
N=4 # Total amount of parallel processes
FILE='jobs.txt'
while read -r line; do 
        echo $line
        $line &

        # Raise counter
        ((X = ++X % N))
        if [ "$X" -eq 0 ]; then
                echo "Waiting"
                wait # Wait on processes to finish
        fi
done < ${FILE}

exit 0

推荐阅读