2010-05-07 9 views
17

Ho uno script di shell C che fa qualcosa di simile:Come utilizzare l'esecuzione parallela in uno script di shell?

#!/bin/csh 
gcc example.c -o ex 
gcc combine.c -o combine 
ex file1 r1  <-- 1 
ex file2 r2  <-- 2 
ex file3 r3  <-- 3 
#... many more like the above 
combine r1 r2 r3 final 
\rm r1 r2 r3 

C'è qualche modo riesco a fare le linee 1, 2 e 3 corsa nel parallelamente invece di una dopo l'altra?

risposta

13

Converti questo in un Makefile con dipendenze appropriate. Quindi è possibile utilizzare make -j per fare eseguire tutto in parallelo.

Si noti che tutti i rientri in un Makefile devono essere TABs. TAB mostra Crea dove sono i comandi da eseguire.

Si noti inoltre che questo Makefile utilizza ora estensioni GNU Make (le funzioni jolly e subst).

Potrebbe assomigliare a questo:

export PATH := .:${PATH} 

FILES=$(wildcard file*) 
RFILES=$(subst file,r,${FILES}) 

final: combine ${RFILES} 
    combine ${RFILES} final 
    rm ${RFILES} 

ex: example.c 

combine: combine.c 

r%: file% ex 
    ex $< [email protected] 
+0

Il tuo '-l combinare' dovrebbe essere' -o combinare' – SiegeX

+0

Vuoi mettere prima la regola 'final' per renderla predefinito? –

+0

Cosa stavo pensando? Fisso. –

7

In bash lo farei;

ex file1 r1 & 
ex file2 r2 & 
ex file3 r3 & 
wait 
... continue with script... 

e generarli in parallelo. È possibile check out this SO thread per un altro esempio.

4
#!/bin/bash 

gcc example.c -o ex 
gcc combine.c -o combine 

# Call 'ex' 3 times in "parallel" 
for i in {1..3}; do 
    ex file${i} r${i} & 
done 

#Wait for all background processes to finish 
wait 

# Combine & remove 
combine r1 r2 r3 final 
rm r1 r2 r3 

Ho leggermente modificato il codice per utilizzare espansione delle parentesi graffe {1..3} invece di codificare i numeri da quando ho capito che hai detto ci sono molti più file di espansione appena 3. Brace rende scalare fino a un numero maggiore banale sostituendo il ' 3 'all'interno delle parentesi graffe a qualsiasi numero necessario.

1

è possibile utilizzare cmd & e attendere dopo

 
#!/bin/csh 
echo start 
sleep 1 & 
sleep 1 & 
sleep 1 & 
wait 
echo ok 

prova:

 
$ time ./csh.sh 
start 
[1] 11535 
[2] 11536 
[3] 11537 
[3] Done     sleep 1 
[2] - Done     sleep 1 
[1] + Done     sleep 1 
ok 

real 0m1.008s 
user 0m0.004s 
sys 0m0.008s 
0

GNU parallelo renderebbe abbastanza simile:

seq 1 3 | parallel ex file{} r{} 

A seconda di come 'ex 'e' combinare 'il lavoro che puoi anche fare:

seq 1 3 | parallel ex file{} | combine 

Per saperne di più su GNU Parallel guardando http://www.youtube.com/watch?v=LlXDtd_pRaY

1

Si potrebbe utilizzare nohup es:

nohup ex file1 r1 &  
nohup ex file2 r2 & 
nohup ex file3 r3 & 
0

xargs può farlo:

seq 1 3 | xargs -n 1 -P 0 -I % ex file% r%

-n 1 è per "una riga per input", -P è per "eseguire ogni riga in parallelo"