pexec

> ### PEXC - összefoglaló

> #### Bevezető

> A `pexec` program alapfeladata egy megadott parancs és/vagy shell-szkript futtatása párhuzamosított környezetben. A programmal egyszerűen lehet a megszokott, szkripteknél használatos eszközöket (ciklusszervezés, átirányítások, pipe-ok, formázás) kombinálni a párhozamos futtatás adta előnyökkel. A programnak alapjában 3 fajta használati módja lehet:

> - Egy adott parancs és/vagy szkript futtatása a lokális gépen, kihasználva a gépben levő több prosszeszor(mag)ot. Ehhez a `pexec` programon kívül további speciális elrendezés (egyéb program, hálozati konfiguráció) nem szükséges. Ebben a módban a párhozamosítás a

>   > `for variable in <set> ; do <command> ; done`

>   ciklushoz hasonlóan fut le, amennyiben a ciklusszervezést lecseréljük a megfelelő `pexec`-hívásra. Az egyedi illetve az összesített kimenetek átírányítása (file-okba, pipe-okba) és átformázása is megoldható, ezutóbbira a kimenetek potenciális keveredése miatt lehet szükség.

> - Egy adott parancs és/vagy szkript futtatása távoli gépeken, egy remote shell segítségével. Ebben a módban a `pexec` programon kívül szükség van egy shell-re, ami a távoli gépekre a bejelentkezést, autentikációt és az egyedi programok végrehajtását végzi (gyakorlatban ez az `ssh`, így garantált a hálózati forgalom biztonsága is). Ebben a módban az egyedi parancsok minden egyes távoli gépen, egy példányban futnak le. A kimenetek átirányítása és átformázására az előző esethez hasonlóan szintén van lehetőség.

> - Egy adott parancs és/vagy szkript futtatása lokális és távoli gépeken, úgy hogy a futtatandó parancsot minden egyes gépre ki lehet osztani. A hálózati forgalom átirányítását, bejelentkezést és autentikációt itt is egy remote shell (`ssh`) látja el, ezentúl azonban minden egyes gépen rendelkezésre kell állnia a `pexec` programnak, mely a lokális elosztást és átirányításokat kezeli le, valamit persze a megfelelő parancsokhoz szükséges egyedi programoknak is rendelkezésre kell állnia, egymással kölcsönösen ekvivalens módon (hiszen egyrészt semmi nem garantálja hogy a parancs egy adott példánya melyik gépen is fog lefutni, másrészt a kiosztás sorrendje függ a pillanatnyi terheléstől is).

> A fenti funkcionalitásokat ki lehet egészíteni (mind lokális, mind távoli futtatások esetén, azaz az összes futtatási módban) egyfajta távirányítással is. Ekkor a (vezérlő)program hálózati vagy UNIX domain socketen keresztül vezérelhető. A vezérlés a következőket takarja:

> - a pillanatnyi státusznak, azaz: a futtatandó feladatok számának, már elvégzett és/vagy függőben levő feladatok számának lekérdezése;
> - kölcsönös kizárás (mutual extension-ok, mutex-ek) megvalósítása, zárolás (lock) illetve a zárolások elengedése (unlock);
> - file-ok kiiratása illetve file-ba való mentés, kölcsönösen kizárt módon;
> - atomi, azaz kölcsönösen kizárt parancsok indítása.
> A vezérlést lehet "kézzel" is csinálni (`netcat` vagy `socket` vagy valami hasonló programmal), azonban a fenti feladatok közvetlenül a `pexec` program távvezérlő módban történő indításával egyszerűen megvalósíthatóak (transzparensen is, azaz távoli gépeken való eloszott futtatásnál automatikusan történik a vezérlés átadása).

> #### Részletes leírás, specifikáció

> Egyelőre csak angolul, lásd itt: pexec.1.html.

> #### Példák

> Identikus futtatás:

> > Amennyiben semmilyen opciót nem adunk meg, csak az indítandó parancsot (és azok argumentumait), a `pexec` program egyszerűen elindítja a programot, a helyi gépen, egy példányban -- mintha nem is lenne a `pexec` az adott parancshívás előtt:

> >     	pexec ssh -X -l user host

> Néhány szám négyzetgyökének kiszámítása:

> > Az alábbi hívás a `bc` program segítségével kiszámítja az 1 és 10 közötti egész számok négyzetgyökét (10000 tizedesjegyre) és az eredményt egyedi fileokba (`sqrt-1.dat`, ..., `sqrt-10.dat`) irányítja át:

> >     	pexec -o sqrt-%s.dat -r `seq 10` -e NUM -n 4 -c 'echo "scale=10000;sqrt($NUM)" | bc'

> > A fenti hívás a futtatásokat 4 szálra (`-n 4`) bontja szét, a gépben levő processzorok/magok számától függetlenül. Az egyes konkrét szám-értékeket a `NUM` környezeti változó segítségével adja át a futtatandó `echo | bc` pipeline-nak. Ez a hívás tehát egyenértékű a

> >     	for NUM in `seq 10` ; do
> >     		echo "scale=10000;sqrt($NUM)" | bc >sqrt-$NUM.dat
> >     	done

> > shell-ciklussal.

> File-ok tartalmának sorbarendezése:

> > Az alábbi példa a megadott file-ok sorait egyenként sorbarendezi, a kimenetet a `*.sort` file-okba tárolja el:

> >     	pexec -r myfiles*.ext -i %s -o %s.sort -- sort

> > A `--` elválasztó csak a könnyebb olvashatóság kedvéért van kiírva (azaz hogy a `pexec` saját argumentumai illetve a futtatandó parancs és/vagy szkript jól elkülöníthető legyen). Az egyenértékű shell-ciklus:

> >     	for f in myfiles*.ext ; do
> >     		sort <$f >$f.sort
> >     	done

> PNG típusú képek JPEG formátumba való konverziója:

> > Az alábbi két példa a konverziót rendre az ImageMagick/`convert` illetve a NetPBM csomag segítségével oldja meg:

> >     	pexec -r *.png -e IMG -c 'convert $IMG ${IMG%.png}.jpeg'

> >     	pexec -r *.png -i %s -o %s.jpeg -c 'pngtopnm | pnmtojpeg'

> > Az előbbi esetben a belső shell-parancs lecseréli a kiterjesztést `png`-ről `jpeg`-re, míg az utóbbi esetben a `*.jpeg` kiterjesztést a már meglevő teljes file-névhez hozzábiggyeszti (így a kimeneti filáok kiterjesztése `*.png.jpeg` lesz).

> JPEG formátumú képek átméretezése:

> > Az alábbi példa az átméretezésen túl demonstrálja a kölcsönösen kizárt file-ba írás/olvasás megvalósítását is. Általában ez akkor hasznos, ha a sok processzoron (illetve több távoli gépen) dolgozunk egyszerre és az egyes futtatások ugyanarról a háttértárolóról dolgoznak. Ebben az esetben ugyanis a párhuzamos terhelés nagyon lelassítja a futtatásokat (random elérés, sok I/O wait, ...). A példában mind az írás mind az olvasás egy-egy mutex segítségével blokkolható olyan szintre, hogy egyszerre csak egy szál férhet hozzá a diszkhez.

> >     	pexec -n 8 -r *.jpg -y unix -e IMG -c \
> >     		'pexec -j -m blockread -d $IMG | \
> >     		jpegtopnm | pnmscale 0.5 | pnmtojpeg | \
> >     		pexec -j -m blockwrite -s th_$IMG'

> > A példa két mutex-et használ, a `blockread` és a `blockwrite` nevezetűt. E kettő garantálja, hogy egyszerre csak egy szál olvasson illetve írjon a diszkre. Amennyiben az írás és az olvasás is ki kell, hogy zárja egymást, ugyanazt a mutex-et kell megadni az olvasás és az írás során egyaránt.

> Rendszerfrissítés több gépen:

> > Az alábbi példa egy egyszerű frissítést (Debian alatt, `apt-get -y upgrade`) mutat be, egyszerre több gépen:

> >     	pexec -n alpha,beta,gamma,delta apt-get -y upgrade

> > A fenti példa a parancsot párhuzamosan lefuttatja az `alpha`, `beta`, `gamma` valamint a `delta` nevezetű gépeken. Ahhoz, hogy a fenti párhuzamosított parancs kavarodás nélkül lefusson, a remote shell-en (`ssh`-n) keresztüli bejelentkezésnek és autentikációnak interaktivitás-mentesnek kell lennie. Amennyiben iterakcióra van szükség (pl. jelszó megadására), a remote shell blokkolni fogja a futtatást, amíg a jelszót/jelszavakat meg nem adjuk. Mivel a standard input-ot minden egyes szál örökli, a jelszó megadása is összekeveredhet az egyes gépek esetében.