如何控制正在运行的进程数?

时间:2016-03-07 19:15:58

标签: linux bash shell unix

我正在做一个shell脚本并且发生了未知情况。我必须执行一定数量的进程,假设12。但是我想限制执行的“执行”。每一次。所以,如果'是3我必须执行3个进程然后3,3和最后3.但我想自动执行,所以我需要监视那些正在运行的进程,当其中一个已完成时,我必须执行其余的进程之一。

经过一番研究,我发现了以下命令:

launch backgroundprocess &
PROC_ID=$!
while kill -0 "$PROC_ID" >/dev/null 2>&1; do
    echo "PROCESS IS RUNNING"
done
echo "PROCESS TERMINATED"

cuonglm提议。

这有助于了解进程是否正在运行。我试图创建12个进程并将它们保存在3个不同的变量中,但它没有正常工作。

processors=3
counter=0

for A in {1..12}
do
    counter=$((counter+1))
    backgroundprocess &
    PID[$A]=$!

    while [ $counter -eq $processors ]
    do
        if kill -0 "$PID[1]" >/dev/null 2>&1;
        then
            counter=$(($counter-1))
            break
        fi
    done
done

你们中的任何人都知道我该怎么做才能做到这一点吗?

3 个答案:

答案 0 :(得分:2)

shell的 jobs 内置命令可用于计算后台进程。

附加文件用于等待后台进程终止。

试一试,测试的脚本如下:

#!/bin/bash --

tmp_file=/tmp/`date "+%Y%m%d%H%M%S$$"`
rm -f "${tmp_file}"
touch "${tmp_file}"
max_nb_processes=12
max_parallel_nb_processes=3
nb_processes=0
while [ $nb_processes -lt $max_nb_processes ]
do
  if [ `jobs -r | wc -l` -lt $max_parallel_nb_processes ]
  then
    (backgroundprocess ; printf "end" "" >> "${tmp_file}")&
    ((nb_processes ++))
  else
    read -t 10 line < "${tmp_file}"
  fi
done
wait

供参考,第一个版本。

下面的测试版本使用了一些轮询:

#!/bin/bash --

poll_time_second=10
max_nb_processes=12
max_parallel_nb_processes=3
nb_processes=0
while [ $nb_processes -lt $max_nb_processes ]
do
  if [ `jobs -r | wc -l` -lt $max_parallel_nb_processes ]
  then
    backgroundprocess &
    ((nb_processes ++))
  else
    sleep $poll_time_second
  fi
done
wait

只要后台进程少于3个,就会在后台启动新进程。

当有3个后台进程时,脚本会在再次检查之前休眠10秒钟。

当12个后台进程启动时,脚本等待表示最后一个进程在终止之前结束。

答案 1 :(得分:1)

这是你脚本的改进。

如果进程存在,

ps -o pid= -p ${PID[$i]}会返回PID

num代表完成的工作数量。

processors=3
counter=0
num=0

for A in {1..12}
do
    counter=$((counter+1))
    sleep 4 &
    if [ $num -eq 0 ]
    then
        PID[$A]=$!
    else
        PID[$num]=$!
    fi
    echo "$A starts"
    echo $counter

    while [ $counter -eq $processors ]
    do
        for i in `seq 1 $processors`
        do
            if [ ! `ps -o pid= -p ${PID[$i]}` ]
            then
                counter=$(($counter-1))
                echo "$i stopped"
                num=$i
                break
            fi
        done
    done
done

答案 2 :(得分:1)

如果您真的不关心让处理器忙碌,那么批量很容易。

processors=3
counter=0

for A in {1..12}
do
    backgroundprocess &
    ((counter++))
    if ((counter == processors)); then
        wait   # Block until all background jobs have completed
        counter=0
    fi
done