2013-05-07 12 views
8

Bir sistemde kayıtlı dosyaları paralel olarak aramak için GNU Parallel kullanılıp kullanılamayacağını değerlendiriyorum. Sistemin her bir günü için sadece bir dosya (doyurma) olabilir (böylece yılda en fazla 366 dosya). Diyelim ki sistemde 3660 dosya var (yaklaşık 10 yıllık veri). Sistem çok CPU çok çekirdekli Linux veya çok CPU Solaris olabilir. Aramayı depolamak ediyorumGNU Paraleline geniş bir komut dizisi nasıl beslenir?

bir diziye (dosya başına bir komutu) dosyalar üzerinde çalışmasına emreder. Ve bu (bash kullanarak) şu anda yapıyorum ama sonra (kesinlikle bir defada tüm 3660 aramalar başlamak istemiyorum) paralel olarak başlatmak için kaç arama üzerinde hiçbir kontrole sahip budur:

#!/usr/bin/env bash 
declare -a cmds 
declare -i cmd_ctr=0 

while [[ <condition> ]]; do 
    if [[ -s $cur_archive_path/log.${doy_ctr} ]]; then 
     cmds[$cmd_ctr]="<cmd_to_run>" 
     let cmd_ctr++ 
    fi 
done 

declare -i arr_len=${#cmds[@]} 
for ((i=0; i<${arr_len}; i++)); 
do 
    # Get the command and run it in background 
    eval ${cmds[$i]} & 
done 
wait 

Ben (otomatik max. CPU'lar/çekirdeklerini anlamaya ve paralel sadece o kadar fazla arama başlayacak olan) parallel kullanacak olursak, nasıl paralel olan dizi cmds yeniden ve yukarıdaki kodu yeniden yazabilirsiniz? diğer alternatif bir dosyaya tüm komutları yazıp cat cmd_file | parallel

+0

3660 dosya verim olamaz benim evren 10 yıl içinde, bilgiçlik taslayan olmak. Ama sen "hakkında" yazdığınıza göre, bunu bildiğimi ve benimkine paralel bir evrenden bakmadığımı sanıyorum (ki bu beni biraz üzüyor) ;-) –

+0

@Adrian Haklısınız; Sıfır yıllık hesaplamak için 'about' ekledim :) –

cevap

6

https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Using-shell-variables yapmak olduğunu söylüyor:

parallel echo ::: "${V[@]}" 

Sen yankı istemiyoruz, bu yüzden:

parallel ::: "${cmds[@]}" 

Eğer ihtiyacınız yoksa Başka bir şey için $ cmds, sonra 'sem' (paralel -semaphore için bir takma addır) kullanın (https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Working-as-mutex-and-counting-semaphore

< koşulunun> ne olduğunu tarif etmediniz. (https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Composed-commands dayalı)

parallel 'if [ -s {} ] ; then cmd_to_run {}; fi' ::: $cur_archive_path/log.{1..3660} 

: sadece bir for döngüsü gibi bir şey yapıyorsun Eğer birlikte tüm senaryoyu yerini alabilir. 10 ardışık artık yıllar olamaz çünkü

+0

Tüm ipuçları için teşekkürler. Ancak bir his var, özellikle cmds dizisinde 1000 eleman/komut varsa, "$ {cmds [@]}" satır içi genişletilirse kabuk patlayacak mı? Komutları bir dosyadan beslemek daha mı güvenli? –

+0

Ayrıca, $ {cmds [@]} 'genişletildiğinde çoklu komutlar arasındaki sınırlayıcı nedir (her komutun sonunda bir'; 'kullanmam gerekir)? Bu nasıl farklıdır? Cat cmd_file | paralel 'yeni bir satır karakteri varsayalım, bir komut ayırıcı olarak kabul edilir? –

+0

130KB komut satırlarını çalıştırabilirim, bu yüzden komutunuz <130 karakter ise, güvende olmalısınız. Ama şahsen ben sadece komutları paralel olarak (yani hem herhangi bir kabuk sınırını hem de geçici bir dosyayı önleyerek) borularım ya da komutları paralel olarak oluşturmama izin veririm. –

İlgili konular