Paralel işleme ile daha iyi bir unix bulmak?


43

Unix find(1)yardımcı programı çok kullanışlı, örneğin belirli özelliklerle eşleşen birçok dosya üzerinde bir işlem yapmama izin veriyor.

find /dump -type f -name '*.xml' -exec java -jar ProcessFile.jar {} \;

Yukarıdakiler, belirli bir dizindeki her XML dosyası üzerinde bir komut dosyası veya araç çalıştırabilir.

Diyelim ki betiğim / programım çok fazla CPU zaman alıyor ve 8 işlemcim var. Bir seferde 8 dosya işlemek için iyi olurdu.

GNU yapmak, -jbayrakla paralel iş işleme olanağı sağlar, ancak findböyle bir işlevselliğe sahip görünmemektedir. Buna yaklaşmakta olan alternatif bir genel iş planlama yöntemi var mı?

Yanıtlar:


65

xargsile -Pseçeneğiyle (işlem sayısı). Diyelim ki tüm günlük dosyalarını 4 cpu'lu bir makinedeki bir dizinde sıkıştırmak istedim:

find . -name '*.log' -mtime +3 -print0 | xargs -0 -P 4 bzip2

-n <number>İşlem başına maksimum iş birimi sayısını da söyleyebilirsiniz . Diyelim ki 2500 dosyam vardı ve dedim ki:

find . -name '*.log' -mtime +3 -print0 | xargs -0 -n 500 -P 4 bzip2

Bu bzip2, her biri 500 dosya içeren 4 işlem başlatır ve ardından ilk işlem bittiğinde son 500 dosya için başlanır.

Önceki cevabın neden kullanıldığından emin değilim xargs ve make orada iki paralel motorunuz var!


7
Find / xargs ile dikkatli olun: varsayılanları çıktı sınırlayıcı olarak newlines'ta bulun, ancak xargs varsayılan olarak girdi sınırlayıcı olarak herhangi bir boşlukta bulunsun. Her ikisinde de güvenli olmak için -0 kullanın ya da giriş sınırlayıcı olarak varsayılan satırlara (eşleşen bulgunun çıktısı) varsayılan GNU paraleline geçin.
efemient

1
İnanılmaz vay! Sadece kontrol ettim ve doğru, xargs -Pseçeneğine sahip!
PP.

Kullanmaya dikkat edin xargs -P- parallel2 iplik aynı anda tam olarak üretime girdiğinde, çıkışın çarpma (sabit bir şekilde) hiçbir zaman sabitlenmemiş bir böcek vardır ...
Vlad

34

GNU paralelinde de yardımcı olabilir.

find /dump -type f -name '*.xml' | parallel -j8 java -jar ProcessFile.jar {}

-j8Argüman olmadan , parallelvarsayılan olarak makinenizdeki çekirdek sayısının :-) olduğuna dikkat edin.


6

"Düzeltmeye" gerek yok find- makeparalelliğin üstesinden gelmek için kendinden yararlan.

İşleminizin bir günlük dosyası veya başka bir çıktı dosyası oluşturmasını sağlayın ve ardından şöyle bir Makefile kullanın:

.SUFFIXES:  .xml .out

.xml.out:
        java -jar ProcessFile.jar $< 1> $@

ve böylece çağırdı:

find /dump -type f -name '*.xml' | sed -e 's/\.xml$/.out/' | xargs make -j8

Daha da iyisi, çıktı dosyasının yalnızca Java işleminin başarılı bir şekilde tamamlanmasından sonra yaratıldığından emin olursanız, bir makedahaki sefere yalnızca işlenmemiş dosyaların yapılmasını sağlamak için bağımlılık işleminden yararlanabilirsiniz .


1
Umarım bu dosya adlarında boşluk veya başka "ilginç" karakterler yoktur; Bunları çok şık bir şekilde yapmayın.
efemient

Mükemmel fikir! Böyle makefiles kullanmayı hiç düşünmedim.
oscfri

3

Bul "+" sembolünü kullanarak doğrudan kullanabileceğiniz paralel bir seçeneğe sahiptir; xargs gerekmez. Grep ile birleştirerek, hızlı bir şekilde eşleşmeleri arayarak ağacınızı parçalayabilir. örneğin, 'foo' dizesini içeren kaynakları dizinindeki tüm dosyaları arıyorum, onu çağırabilirim.
find sources -type f -exec grep -H foo {} +


12
Find kılavuzunu okuyarak, -exec command +sözdiziminin paralel olarak çalışmadığını ancak birçok dosyayı bir arada "gruplandırdığınızı" ve aynı anda birden fazla dosyayı içeren komutu çalıştırdığını görebilirsiniz. Grep, hedeflerine paralel olarak bakabilir.
Gyscos
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.