V adresáři mám spoustu obrázků PNG. Mám aplikaci s názvem pngout, kterou spouštím ke kompresi těchto obrázků. Tato aplikace je volána skriptem, který jsem udělal. Problém je v tom, že tento skript dělá jeden po druhém, něco takového:
FILES=(./*.png)
for f in "${FILES[@]}"
do
echo "Processing $f file..."
# take action on each file. $f store current file name
./pngout -s0 $f R${f/.//}
done
Zpracování pouze jednoho souboru najednou zabere spoustu času. Po spuštění této aplikace vidím, že CPU je jen 10%. Zjistil jsem tedy, že mohu tyto soubory rozdělit do 4 dávek, vložit každou dávku do adresáře a spustit 4 ze čtyř oken terminálu, čtyř procesů, takže mám čtyři instance svého skriptu, který současně zpracovává tyto obrázky a úloha zabere 1/4 času.
Druhým problémem je, že jsem ztratil čas rozdělováním obrázků a dávek a kopírováním skriptu do čtyř adresářů, otevřením 4 oken terminálu, bla bla…
Jak to udělat s jedním skriptem, aniž byste museli cokoli rozdělovat?
Mám na mysli dvě věci:zaprvé, jak mohu z bash skriptu spustit proces na pozadí? (stačí přidat &na konec?) Za druhé:jak zastavím odesílání úkolů na pozadí po odeslání čtvrtého úkolu a nechám skript čekat, až úkoly skončí? Chci říct, jen posílat nový úkol na pozadí, jakmile jeden úkol skončí, přičemž vždy zůstanou 4 úkoly paralelně? pokud to neudělám, smyčka spustí miliony úkolů na pozadí a CPU se ucpe.
Přijatá odpověď:
Pokud máte kopii xargs
který podporuje paralelní provádění s -P
, můžete to jednoduše udělat
printf '%s
Linux