2012-06-18 26 views
10

我在運行命令的shell中編寫腳本,花費2分鐘。每次。此外,我們無能爲力。但是如果我想在腳本中運行這個命令100次,那麼總時間將是200分鐘。這會造成一個大問題。沒有人想等200分鐘。我想要的是並行運行所有100個命令,以便輸出將在2分鐘內完成,或者可能需要更多時間,但不要花費200分鐘。Shell腳本中的並行處理或線程

將意識到,如果任何機構可以幫助我在此以任何方式。

+0

[你嘗試過什麼(http://mattgemmell.com/2008/12/08/what-have-you-tried/)? – ghoti

+0

另外,你使用的是什麼外殼? TCSH? zsh的? PD-KSH?魚? – Graham

回答

10

...運行所有100個命令平行,這樣輸出會在2分鐘

,如果你的系統上有200個處理器,這是唯一可行的。

有在外殼腳本沒有這樣的實用程序/指令並行運行的命令。你可以做的是在後臺運行命令:

for ((i=0;i<200;i++)) 
do 
    MyCommand & 
done 

隨着&(背景),每個執行儘快安排。但是這並不能保證你的代碼將在200分鐘內執行。這取決於您的系統上有多少處理器。

如果你只有一個處理器和指令的每次執行(即需要2分鐘)正在做一些計算,2分鐘,然後處理器做了一些工作,這意味着沒有等待的週期。在這種情況下,並行運行命令不會有幫助,因爲只有一個處理器也不是免費的。所以,這些流程將等待輪到他們執行。

如果你有一個以上的處理器,那麼上面的方法(循環)減少總的執行時間可能會有所幫助。

+1

如果腳本是IO綁定的,則不需要200個處理器。事實上,只有一個處理器就可以實現顯着的提速。 –

+0

@WilliamPursell沒錯。但它確實取決於該命令爲此做了什麼* 2分鐘*。 –

4

正如@KingsIndian說,你可以後臺任務,這有​​點讓他們並行運行。除此之外,您還可以跟蹤它們的進程的ID:

#!/bin/bash 

# Function to be backgrounded 
track() { 
    sleep $1 
    printf "\nFinished: %d\n" "$1" 
} 

start=$(date '+%s') 

rand3="$(jot -s\ -r 3 5 10)" 

# If you don't have `jot` (*BSD/OSX), substitute your own numbers here. 
#rand3="5 8 10" 

echo "Random numbers: $rand3" 

# Make an associative array in which you'll record pids. 
declare -A pids 

# Background an instance of the track() function for each number, record the pid. 
for n in $rand3; do 
    track $n & 
    pid=$! 
    echo "Backgrounded: $n (pid=$pid)" 
    pids[$pid]=$n 
done 

# Watch your stable of backgrounded processes. 
# If a pid goes away, remove it from the array. 
while [ -n "${pids[*]}" ]; do 
    sleep 1 
    for pid in "${!pids[@]}"; do 
    if ! ps "$pid" >/dev/null; then 
     unset pids[$pid] 
     echo "unset: $pid" 
    fi 
    done 
    if [ -z "${!pids[*]}" ]; then 
    break 
    fi 
    printf "\rStill waiting for: %s ... " "${pids[*]}" 
done 

printf "\r%-25s \n" "Done." 
printf "Total runtime: %d seconds\n" "$((`date '+%s'` - $start))" 

你也應該看看上coprocesses Bash的文檔。

13

GNU Parallel是你想要的,除非你想推倒重來。這裏有一些更詳細的examples,但它的短:

ls | parallel gzip # gzip all files in a directory