2014-09-23 26 views
1

我需要使用/ Cobra在後臺運行各種作業。如何計算BASH中的進程,包括那些剛啓動的進程?

我有32個內核,我想保持幾個免費,否則我的機器太慢,做其他事情。

在這段代碼我檢查的進程數用ps,只啓動到30

最大數量然而,「PS」似乎並沒有給信息及時。即使我等待3秒鐘,ps有時會聲明匹配進程的數量。這大概是他們剛剛開始在後臺開始的時候。

無論如何,從ps(或其他方面)得到更好的答案,我唯一的解決方案是睡更長時間,但這有點笨重。

#!/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 

回答

0

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 
0

您可以使用/ proc虛擬文件系統:

CURRENTLY_RUNNING = $(找到的/ proc/[0-9] */EXE 2>/dev/null | grep眼鏡蛇| wc -l)

另一種方法是在每次啓動/眼鏡蛇時只創建一個PID文件並對這些文件進行計數。唯一的問題就是刪除PID文件。這可以通過一個包裝腳本存檔:

/cobra.sh:

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

並非所有的操作系​​統都有'/ proc'文件系統。 – chepner 2014-09-23 12:33:58

0

,而不是查詢的進程數,自己保持的計數器。

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 
0

您可以嘗試這一行替換您的整個腳本:

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

xargs命令將dispath的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秒的總運行時間。