【问题标题】:How to count processes in BASH, including those JUST started?如何计算 BASH 中的进程,包括刚刚启动的进程?
【发布时间】:2014-11-17 15:36:21
【问题描述】:

我需要使用 /Cobra 在后台运行各种作业。

我有 32 个内核,我想让几个内核保持空闲,否则我的机器会变得太慢而无法执行其他操作。

在这段代码中,我使用 ps 检查进程的数量,并且最多只能启动 30 个。

但是,“ps”似乎无法及时提供信息。即使我等待 3 秒,ps 有时也会在声明匹配进程的数量下。这大概是他们刚刚在后台开始的时候。

有没有办法从 ps (或 otehrwise)那里得到更好的答案,我唯一的解决办法就是睡更长时间,但这有点笨拙。

#!/bin/sh
#set -x

while true
do
    NUMRUNNING=`ps | egrep FormsApplic | wc -l` 

    JOBS=`cat jobs.lst | wc -l`
    if [ $JOBS -gt 0 ]
    then

        MAXSTART=$((30-$NUMRUNNING))
        NUMTOSTART=$JOBS

        if [ $NUMTOSTART -gt $MAXSTART ]
        then
            NUMTOSTART=$MAXSTART
        fi 
        for ((i=1;i<=$NUMTOSTART;i++))
        do
            JOB=`head -n1 jobs.lst`
            echo $JOB >> /tmp/jobsStarted
            sed -i 1d jobs.lst
            /cobra $JOB &

        done

    fi

    LASTNUMRUNNING=$NUMRUNNING
    sleep 3
done

【问题讨论】:

    标签: bash process sleep ps


    【解决方案1】:

    ps 应该立即列出进程。我不确定你出了什么问题,但这个脚本有一些改进。其中最主要的是使用pgrep 而不是解析ps。如果它解决了您的问题,请告诉我:

    while true
    do
        NUMRUNNING=$(pgrep -c FormsApplic)
    
        JOBS=$(wc -l jobs.lst)
        if [ "$JOBS" -gt 0 ]
        then
    
            MAXSTART=$((30-$NUMRUNNING))
            NUMTOSTART=$JOBS
    
            if [ "$NUMTOSTART" -gt "$MAXSTART" ]
            then
                NUMTOSTART="$MAXSTART"
            fi 
            for ((i=1;i<="$NUMTOSTART";i++))
            do
                JOB=$(head -n1 jobs.lst)
                echo "$JOB" >> /tmp/jobsStarted
                sed -i 1d jobs.lst
                /cobra "$JOB" &
            done
    
        fi
    
        LASTNUMRUNNING=$NUMRUNNING
        sleep 3
    done
    

    【讨论】:

      【解决方案2】:

      您可以使用 /proc 伪文件系统:

      CURRENTLY_RUNNING=$(find /proc/[0-9]*/exe 2>/dev/null |grep cobra |wc -l)

      另一种方法是在每次启动 /cobra 时创建一个 PID 文件,然后对文件进行计数。唯一的问题是删除 PID 文件。这可以通过包装脚本存档:

      /cobra.sh:

      touch /var/run/cobra/run.$$
      /cobra
      rm /var/run/cobra/run.$$
      

      【讨论】:

      • 并非所有操作系统都有/proc 文件系统。
      【解决方案3】:

      与其查询进程数,不如自己维护一个计数器。

      num_running=0
      while read job; do
          if [ $num_running -eq $max_start ]; then
              # wait for the oldest job to complete. Not ideal,
              # since another job might complete before that one.
              wait $(jobs -p | head -n 1)
              num_running=$((num_running  - 1))
          fi
          /cobra $JOB &
          num_running=$((num_running+1))
      done < jobs.lst
      

      如果您使用的是bash 4.3,您可以(终于!)等待任意作业完成,而不是所有作业的特定子集。

      num_running=0
      while read job; do
          if [ $num_running -eq $max_start ]; then
              # Wait for any one background job to complete
              wait -n
              num_running=$((num_running  - 1))
          fi
          /cobra $JOB &
          num_running=$((num_running+1))
      done < jobs.lst
      

      【讨论】:

        【解决方案4】:

        您可以尝试用此行替换整个脚本:

        < jobs.lst xargs -n 1 -P 30 /cobra 
        

        xargs 命令将转移jobs.lst 的每一行作为/cobra 命令的参数,最多创建30 个并行进程。

        这是一个综合示例:

        $ cat jobs.lst 
        1
        2
        3
        4
        
        $ time < jobs.lst xargs -n 1 -P 2 sleep & 
        [1] 5291
        $ ps aux|grep -i [s]leep|grep -v xargs
        user       5297   0.0  0.0  2426644    320 s002  S     3:25PM   0:00.00 sleep 2
        user       5296   0.0  0.0  2426644    320 s002  S     3:25PM   0:00.00 sleep 1
        $ ps aux|grep -i [s]leep|grep -v xargs
        user       5297   0.0  0.0  2426644    320 s002  S     3:25PM   0:00.00 sleep 2
        user       5303   0.0  0.0  2426644    320 s002  S     3:25PM   0:00.00 sleep 3
        $ ps aux|grep -i [s]leep|grep -v xargs
        user       5309   0.0  0.0  2426644    320 s002  S     3:25PM   0:00.00 sleep 4
        user       5303   0.0  0.0  2426644    320 s002  S     3:25PM   0:00.00 sleep 3
        $ ps aux|grep -i [s]leep|grep -v xargs
        user       5309   0.0  0.0  2426644    320 s002  S     3:25PM   0:00.00 sleep 4
        $ 
        real    0m6.014s
        user    0m0.002s
        sys 0m0.009s
        

        您可以看到每个时刻有 2 个作业并行运行,总运行时间为 2+4=6 秒。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-06-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-11
          • 2012-04-07
          • 2012-12-19
          相关资源
          最近更新 更多