Mitől többszálú?
Egy program többszálú, ha futása közben újabb szálakat hoz létre a fő szál mellett. Ezeken a mellékszálakon valamely részfeladatot (függvény) számol ki a többi szállal párhuzamosan.
Minden program legalább egyszálú, hiszen a program utasításainak végrehajtása magán a fő szálon kezdődik és fejeződik be. Ugyanakkor a szálak között nincs ilyen megkülönböztetés, hogy ’fő’ meg ’mellék’ szál, minden szál egyenrangú.
Ennek megfelelően kijelenthetjük, hogy
- egy program akkor aktív (fut), ha legalább egy szálon még hajt végre utasításokat (ez nem feltétlenül a fő szál)
- egy program leállt, ha nincs már egyetlen működő, aktív szál sem
Elképzelhető, hogy a fő szál indulása után létrehoz további szálakat, majd leáll. Ekkor a program futása még nem áll meg, mivel vannak szálak, akik működnek. A program akkor áll le, ha minden szál leállt.
A szál (thread) a ’végrehajtási szál’ (thread of execution) rövidítése. Ez valójában utasítások egy sorozata, mely önmagában is valamely részfeladat ellátására szolgál.
Ha több szálunk is van, akkor azok utasításai egymással párhuzamosan hajthatóak végre. Ugyanakkor az egy program által indított több szál ugyanazon változóterületen osztozik, vagyis elképzelhető a szálak közötti közös változók fogalma.
Ennek megfelelően a szálak egymással közös változókon keresztül kommunikálnak.
Mivel a szál fogalmának ezen része (önmagában is valamely részfeladat ellátására szolgál) hasonlít a függvény fogalmához, így nem meglepő, hogy a legtöbb programozási nyelven a szálhoz tartozó utasítássorozatot egy függvény kódja adja meg. Vagyis egy közönséges függvényt tudunk külön szálon indítani.
Egy processzoros gépek
Egyprocesszoros gépeken a több szálú (multi-threaded) programok végrehajtása nem triviális, hiszen a mikroprocesszor egy időben csak egyetlen utasítás végrehajtására képes.
Ennek megfelelően az eljárás az, hogy a processzor hol az egyik, hol a másik szálról emeli ki a következő végrehajtandó utasítást, és hajtja azt végre. Ez azt a benyomást kelti, hogy minden szálon halad a végrehajtás, így párhuzamos a végrehajtás.
A váltás a szálak között nem minden egyes utasítás után történik, mivel a szálváltás aránylag lassú művelet. A processzor minden szálról több száz gépi kódú utasítást hajt végre, mielőtt szálat váltana.
Vegyük észre, hogy egy processzor esetén hiába készítünk több szálú programot – annak futási ideje nem rövidül, hiszen a végrehajtandó utasítások mennyisége nem csökkent le. Sőt, a szálváltások miatt jelentkező többletmunka még lassítja is (ha nem is jelentősen) a futási időt.
Szálvátások időzítése
A szálak közötti váltás ütemezése nem egyszerű feladat. Figyelembe kell venni pl. a szálak prioritását. Amennyiben valamely szál prioritása nagyobb, úgy neki több processzoridőt kell biztosítani, mint egy gyengébb prioritású szálnak. Ezt úgy érik el, hogy a magasabb prioritású szálról a processzor több utasítást hajt végre, majd vált a gyengébb szálra, de onnan kevesebb utasítást hajt végre mielőtt visszaváltana a magasabb szálra.
A váltás a szálak között alapvetően kétfajta ütemezéssel történhet:
- Kooperatív: a szál átadja a vezérlést (megengedi a szálváltást) amikor ő jónak látja
- Preemtív: az operációs rendszer központi ütemezőjének joga van szálváltást kezdeményezni
Ez utóbbi biztonságosabb, mivel az első esetben egy hibás szál blokkolhatja a teljes szálváltási mechanizmust, amitől a kezelőnek az a benyomása támad, hogy a számítógépe lefagyott.
Több processzoros gépek
Amennyiben a számítógépünkbe több processzor is van szerelve (2,4,8,16,32 processzor), úgy a szálak végrehajthatóak úgy is, más-más processzor dolgoz fel más-más szálat. Ez ekkor valódi párhuzamos végrehajtást jelent. Ekkor nyilván (optimális esetben) nincs szükség szálváltásokra.
Amennyiben azért hozunk létre szálakat, hogy a párhuzamos feldolgozás miatt a program futási ideje csökkenjen – úgy többprocesszoros gépek esetén ez be is fog következni.
Természetesen itt is jelentkeznek problémák. Mivel a szálak között közös változók (memóriaterületek) vannak, amennyiben a valódi párhuzamos végrehajtás során ugyanarra a memóriaterületre egy időben több szál is írni készül – úgy azt szinkronizálni kell.
Több-magos processzorok
A több processzormaggal szerelt mikroprocesszorok a szálak párhuzamos feldolgozhatósága szempontjából a több processzoros gépeknek felelnek meg. Bár csak egyetlen processzor chip van az alaplapra szerelve, de ezen belül több mag is elhelyezkedik, így a szálak utasításait különállóan, egymással párhuzamosan képes feldolgozni a gép.
Nyilván figyelembe kell venni, hogy csak addig beszélhetünk valódi párhuzamos végrehajtásról, amíg nem készítünk több szálat, mint ahány processzorunk, vagy processzormagunk van. Amint meghaladjuk a fizikai végrehajtó egységek számát, úgy újra a szálváltások, és a szimulált párhuzamos végrehajtás kerül szóba.