2012-01-24 5 views
6

Le CPU odierne comprendono in genere diversi core fisici. Questi potrebbero anche essere multi-thread in modo che il kernel di Linux veda un numero piuttosto elevato di core e di conseguenza inizi più volte lo scheduler di Linux (uno per ogni core). Quando si eseguono più attività su un sistema Linux, lo scheduler ottiene normalmente una buona distribuzione del carico di lavoro totale su tutti i core Linux (potrebbe essere lo stesso nucleo fisico).Come (banalmente) parallelizzare con la shell di Linux avviando un'attività per core Linux?

Ora, ad esempio, ho un numero elevato di file da elaborare con lo stesso eseguibile. Io di solito faccio con il comando "find":

find <path> <option> <exec> 

Tuttavia, questo inizia un solo compito, in qualsiasi momento e attende fino al suo completamento prima di avviare l'operazione successiva. Pertanto, solo un core in qualsiasi momento è in uso per questo. Ciò lascia la maggior parte dei core inattivi (se questo comando di ricerca è l'unica attività in esecuzione sul sistema). Sarebbe molto meglio avviare N task nello stesso tempo. Dove N è il numero di core visti dal kernel di Linux.

Esiste un comando che lo farebbe?

+1

Dai un'occhiata all'utilità parallela GNU. Non so come si adatti al tuo particolare problema, ma ho una lettura: http://www.gnu.org/software/parallel/ –

+1

Sì, hai ragione. Il parallelo GNU è effettivamente destinato a questo utilizzo. Può essere usato come sostituto di "xargs". – ritter

+0

@Daniel: Sembra che dovresti postarlo come risposta. –

risposta

7

Utilizzare find con l'opzione -print0. Condurlo a xargs con l'opzione -0. xargs accetta anche l'opzione -P per specificare un numero di processi. -P deve essere utilizzato in combinazione con -n o -L.

Leggi man xargs per ulteriori informazioni.

Un comando di esempio: find . -print0 | xargs -0 -P4 -n4 grep searchstring

+0

Mille grazie per la risposta! Poiché GNU parallel non è un componente della mia distribuzione, xargs è la scelta (al momento!). – ritter

2

Se avete GNU Parallel http://www.gnu.org/software/parallel/ installato si può fare questo:

find | parallel do stuff {} --option_a\; do more stuff {} 

È possibile installare GNU parallelo semplicemente:

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

Guarda il video introduttivi per GNU Parallelo per saperne di più: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

+0

Grandi video introduttivi. Grazie molto!! Sfortunatamente il parallelo GNU non lo ha ancora fatto in Ubuntu 11.10. Incredibile, un ottimo strumento! Tuttavia, ho letto suggerimenti che lo farà in 12.04. Buone notizie!! – ritter

+0

Non è in http://www.ubuntuupdates.org/package_metas/list?name=parallel, quindi mi chiedo dove leggi questi suggerimenti. –

0

Gnu parallel o xargs -P è probabilmente un modo migliore per gestirlo, ma è possibile anche scrivere una sorta di framework multi-tasking in bash. È un po 'disordinato e inaffidabile, tuttavia, a causa della mancanza di alcune strutture.

#!/bin/sh 

MAXJOBS=3 
CJ=0 
SJ="" 

gj() { 
    echo ${1//[][-]/} 
} 

endj() { 
    trap "" sigchld 
    ej=$(gj $(jobs | grep Done)) 
    jobs %$ej 
    wait %$ej 
    CJ=$(($CJ - 1)) 
    if [ -n "$SJ" ]; then 
     kill $SJ 
     SJ="" 
    fi 
} 
startj() { 
    j=$* 
    while [ $CJ -ge $MAXJOBS ]; do 
     sleep 1000 & 
     SJ=$! 
     echo too many jobs running: $CJ 
     echo waiting for sleeper job [$SJ] 
     trap endj sigchld 
     wait $SJ 2>/dev/null 
    done 
    CJ=$(($CJ + 1)) 
    echo $CJ jobs running. starting: $j 
    eval "$j &" 
} 

set -m 

# test 
startj sleep 2 
startj sleep 10 
startj sleep 1 
startj sleep 1 
startj sleep 1 
startj sleep 1 
startj sleep 1 
startj sleep 1 
startj sleep 2 
startj sleep 10 

wait