8. tétel - Párhuzamos tervezési minták II.
Mutassa be a Master/Worker tervezési mintát! Ismertesse a tulajdonságait, az általános felépítését, valamint tipikus használati eseteit! Mutassa be a Fork/Join tervezési mintát!
Master/Worker
A Master/Worker minta azokban az esetekben használható hatékonyan, amikor a terheléselosztás nehezen valósítható meg a szálak között és ezért nem célszerű előre műveletvégzőket rendelni adott feladatokhoz.
Akkor is megoldást nyújthat, ha a logika intenzív része nem számlálós ciklusba rendezett, mérete nem ismert előre, és nem is becsülhető meg.
Tehát akkor jó, amikor:
- nagy mennyiségű, nem összefüggő adatunk van
- jó terheléseloszlás mellett szeretnénk elvégezni a feladatokat
Általános felépítése
flowchart TB
MI[Master Inicializál] --> WI & W2 & W3 & W4
subgraph W1[W1: worker életciklus]
WI[Inicializálás] --> WF[Feladat kérése a Mastertől] --> WV[Feladat végrehajtása] --> COND{Van még megoldatlan feladat?}
COND -->|Van| WF
COND -->|Nincs| WL[Leállás]
end
subgraph W2
end
subgraph W3
end
subgraph W4
end
WL & W2 & W3 & W4 --> MB[Master begyűjti az eredményeket] --> ML[Master leáll]
-
Master inicializál
- Betölti a problémát
- deklarálja a részproblémák tárolására alkalmas szerkezetet,
- betölti a részfeladatokat,
- majd indítja a Worker elemeket.
-
Worker életciklus
a) Inicializálás
b) Feladat kérése a Mastertől
c) Végrehajtás
d) Ha van még megoldatlan feladat, akkor ugrás a b) pontra
e) Kilépés -
Master begyűjti és összegzi az eredményeket
-
Leállítás
Tulajdonságok
- A feladatokat tartalmazó adatszerkezet (bag of tasks) jellemzően egy szálbiztos sor
- A feladatok nincsenek statikusan hozzárendelve a műveletvégzőkhöz
- A terheléselosztás automatikus (egy szál új feladatot kap, ha végzett az előzővel)
- Jól skálázható: ha a feladatok száma jóval nagyobb a műveletvégzők számánál, a párhuzamos gyorsítás közel lineáris
- A Master a feladatok legyártása után Workerré válhat
- Átalakítások:
- Work stealing: a workereknek saját munkasora van, és lophatnak egymáséról ha kifogytak
- Hibatolerálás megoldható, ha ugyanazt a feladatot több workernek is kiosztjuk
- Hátrány:
- kihívás lehet a befejezés detektálása
- pl. ha a Master már a gyártás közben indítja a workereket, szükség lehet egy logikai változóra is, a sor ürességének ténye nem elég
- poison pill: speciális feladat, ami azt jelzi, hogy nincs már feladat, és leállhat a worker
- ha a szálaknak a műveletvégzés során kommunikálni kell egymással, vagy a feladatok között függés van, akkor ez a minta nem alkalmazható.
- kihívás lehet a befejezés detektálása
Fork/Join
Abban az esetben használjuk a Fork/Join mintát, ha a részproblémák létrehozása dinamikus, a bemeneti paraméter függvénye. Ekkor nem ismert előre a részfeladatok száma.
Tipikus használati esete az „oszd meg és uralkodj” elvű problémák, amikor a feladatot addig bontjuk részproblémákra, amíg el nem érünk az alapesetig, majd visszafelé felépítjük a megoldást.
A minta neve a szálak elágazáskori létrejöttéről (fork), és később a szinkronizációkor való visszacsatlakozásról (join) kapta.
Az implementációkor a fő problémát a szálak létrehozásából, menedzsmentjéből és megszüntetéséből adódó overhead okozza, amellyet kétféle leképezéssel oldhatunk meg.
A direkt leképezés során a szálak és a részprobléma létrehozása egyszerre történik. A forráskódban, ahol szükséges, létrejön a szál, a szülő szál pedig blokkol, amíg a gyermek nem végzett a feladatával. Tehát a program egy szállal indul, amelyről egyre több szál ágazik le, és várakozik ezek befejeződésére. A gyermek szálakból további szálak ágazhatnak le.
Az indirekt leképezés az előbb kialakuló jelentős overheadet hívatott csökkenteni. A direkt lekézesés során a szálak létrehozása a teljes végrehajtást lassítja, illetve ronthatja a hatékonyságot. Szálak létrehozása és megszüntetése helyett használható az úgynevezett thread pool, amikor a program indításakor újrahasznosítható szálak jönnek létre, feladatuk befejeztével pedig visszakerülnek a poolba. Ezzel a szerkezettel a feladatokhoz nem kapcsolódnak dedikált szálak, tehát csökken a létrehozásból, ütemezésből és megszüntetésből adódó overhead.
A minta szorosan kapcsolódik a Loop Parallelism és a Master/Worker mintához is.