2012-06-18 9 views
10

Ich schreibe ein Skript in der Shell, in dem ein Befehl ausgeführt wird und dauert 2 min. jedes Mal. Außerdem können wir damit nichts anfangen. Aber wenn ich diesen Befehl 100 mal im Skript ausführen möchte, dann wäre die Gesamtzeit 200min. und das wird ein großes Problem schaffen. Niemand möchte 200 Minuten warten. Was ich will, ist, alle 100 Befehle parallel zu laufen, so dass die Ausgabe in 2min kommt, oder vielleicht ein bisschen länger, aber nimm nicht 200min.Parallele Verarbeitung oder Threading in Shell-Skripts

wird es geschätzt werden, wenn irgendeine Körper mir in dieser Hinsicht helfen kann.

+0

[Was haben Sie versucht] (http://mattgemmell.com/2008/12/08/what-have-you-tried/)? – ghoti

+0

Welche Shell verwenden Sie? tcsh? Zsh? pd-ksh? Fisch? – Graham

Antwort

10

... laufen alle 100 Befehle parallel, so dass Ausgang

Dies ist nur möglich in 2min kommen, wenn Sie 200 Prozessoren auf Ihrem System haben.

Es gibt kein solches Dienstprogramm/Befehl im Shell-Skript, um Befehle parallel auszuführen. Was Sie tun können, ist Ihr Befehl im Hintergrund ausgeführt werden:

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

Mit & (Hintergrund), jede Ausführung so schnell wie möglich geplant ist. Dies garantiert jedoch nicht, dass Ihr Code in weniger als 200 Minuten ausgeführt wird. Es hängt davon ab, wie viele Prozessoren auf Ihrem System vorhanden sind.

Wenn Sie nur einen Prozessor haben und jede Ausführung des Befehls (dauert 2 Minuten) eine Berechnung für 2 Minuten durchführt, dann macht der Prozessor etwas Arbeit, dh es werden keine Zyklen verschwendet. In diesem Fall wird das Ausführen der Befehle nicht parallel ausgeführt, da es nur einen Prozessor gibt, der auch nicht frei ist. Die Prozesse warten also nur darauf, dass sie an der Reihe sind.

Wenn Sie mehr als einen Prozessor haben, kann die obige Methode (for-Schleife) dabei helfen, die gesamte Ausführungszeit zu reduzieren.

+1

Wenn das Skript IO gebunden ist, benötigen Sie keine 200 Prozessoren. Tatsächlich kann eine wesentliche Beschleunigung mit nur einem Prozessor erreicht werden. –

+0

@WilliamPursell Das stimmt. Aber es hängt wirklich davon ab, was der Befehl dafür macht * 2 Minuten *. –

4

Wie @KingsIndian sagte, können Sie Hintergrundaufgaben, die sie parallel laufen lassen. Darüber hinaus können Sie auch von ihnen durch Prozess-ID zu verfolgen:

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

Sie sollten auch einen Blick auf die Bash-Dokumentation auf coprocesses nehmen.

13

GNU Parallel ist was Sie wollen, es sei denn, Sie wollen das Rad neu erfinden. Hier sind einige weitere detaillierte examples, aber die kurze davon:

ls | parallel gzip # gzip all files in a directory 
Verwandte Themen