2011-12-01 18 views
0

我有一個腳本,循環和每次迭代調用,在後臺像下面KSH:約束,可以同時運行的線程數量

xn_run_process.sh

... 
for each in `ls ${INPUT_DIR}/MDX*.txt` 
do 
     java -Xms256m -Xmx1024m -cp ${CLASSPATH} com.wf.xn.etcc.Main -config=${CONFIG_FILE} 
     ... 
     for SCALE_PDF in `ls ${PROCESS_DIR}/*.pdf` 
     do 
      OUTPUT_AFP=${OUTPUT_DIR}/`basename ${SCALE_PDF}` 
      OUTPUT_AFP=`print ${OUTPUT_AFP} | sed s/pdf/afp/g` 
      ${PROJ_DIR}/myscript.sh -i ${SCALE_PDF} -o ${OUTPUT_AFP} & 
      sleep 30 
     done 
done 

當我做運行一個線程這個,我只認爲一次只能同時執行5個線程的myscript.sh,然而事情發生了變化,而這個列表執行了30個線程,每個線程的處理都很繁瑣。如何將併發進程數限制爲5?

回答

1

雖然這在純shell腳本中是可行的,但最簡單的方法是使用並行化工具,如GNU parallel或GNU make。 Makefile示例:

SOURCES = ${SOME_LIST} 
STAMPS = $(SOME_LIST:=.did-run-stamp) 

all : $(STAMPS) 

%.did-run-stamp : % 
    /full/path/myscript.sh -f $< 

然後調用make作爲make -j 5

+0

喜你叫'使-j 5'在腳本中或在外殼上?並且你不必爲'make'設置一個'target'? –

+0

你能解釋一下關於'did-run-stamp'嗎? –

+1

在shell中,在所顯示的文件是'Makefile'的目錄中。在默認情況下,使用第一個目標(按照慣例是'all'),而'did-run-stamp'只是一個不存在的虛擬文件名,並且作爲make的目標。如果您使用原始文件名,make會檢查所有文件是否存在,並且無需執行操作即可成功。 – thiton

1

使用GNU並行(調整-j你認爲合適的,如果你想的CPU#刪除它。):

for each in `ls ${INPUT_DIR}/MDX*.txt` 
do 
     java -Xms256m -Xmx1024m -cp ${CLASSPATH} com.wf.xn.etcc.Main -config=${CONFIG_FILE} 
     ... 
     for SCALE_PDF in `ls ${PROCESS_DIR}/*.pdf` 
     do 
      OUTPUT_AFP=${OUTPUT_DIR}/`basename ${SCALE_PDF}` 
      OUTPUT_AFP=`print ${OUTPUT_AFP} | sed s/pdf/afp/g` 
      sem --id myid -j 5 ${PROJ_DIR}/myscript.sh -i ${SCALE_PDF} -o ${OUTPUT_AFP} 
     done 
done 
sem --wait --id myid 

sem是GNU並行的一部分。

這將使5個作業繼續運行,直到剩下5個作業。然後它將允許你的java在結束最後5時運行。sem --wait也將等到最後5個完成。

或者:

for each ... 
    java ... 
    ... 
    ls ${PROCESS_DIR}/*.pdf | 
    parallel -j 5 ${PROJ_DIR}/myscript.sh -i {} -o ${OUTPUT_DIR}/{/.}.afp 
done 

這將並行運行5個工作崗位,只有讓Java運行時,所有的作業都完成了。

另外,您可以使用GNU並行的手冊頁描述的隊列招:https://www.gnu.org/software/parallel/man.html#example__gnu_parallel_as_queue_system_batch_manager

echo >jobqueue; tail -f jobqueue | parallel -j5 & 
for each ... 
    ... 
    ls ${PROCESS_DIR}/*.pdf | 
    parallel echo ${PROJ_DIR}/myscript.sh -i {} -o ${OUTPUT_DIR}/{/.}.afp >> jobqueue 
done 
echo killall -TERM parallel >> jobqueue 
wait 

這將運行java,然後添加到運行到一個隊列的作業。在添加作業之後,java將立即運行。任何時候都會從隊列中運行5個作業,直到隊列爲空。

您可以通過簡單的安裝GNU並行:

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel 
chmod 755 parallel 
cp parallel sem 

觀看介紹視頻,以瞭解更多:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1並通過教程(男子parallel_tutorial)行走。你命令愛你。

0

如果你有ksh93的檢查,如果JOBMAX可用:

JOBMAX

This variable defines the maximum number running background 
jobs that can run at a time. When this limit is reached, the 
shell will wait for a job to complete before staring a new job.