Valahol a programban valami probléma merül fel (a kapcsolat megszakad a távoli féllel, a számítás túlcsordul, a tömb indexe a tartományon
kívül esik, ...).
A következő megoldások jöhetnek szóba (történelmi áttekintés):
- 1. hibaüzenettel abortál a program: ezt úgy is hívhatnánk, hogy nincs hibakezelés, és ez az, amit a Pliant is tett egészen a 12-es
verzióig.
- 2. a futási szálat átadni egy hibakezelőnek, ami lekezeli a hibát: ez az amit a C++ és társai tesznek.
- 3. feljegyezni a hibát és folytatni: ez az, amit a Pliant tesz most.
Az első megoldással, amire azt is mondhatjuk, hogy nincs hibakezelés az a baj, hogy nem ad semmilyen lehetőséget a folytatásra még, ha csak
kicsi is a hiba. Ennek következtében a korai Pliant verziókban a hibakezelést a fordító végezte, ami ne volt túl megbízható.
A második megoldást optimistának is lehetne hívni: azt gondolja, ha kiüríti a stacket és megsemmisíti a lokális változókat, akkor biztonságosan
át lehet adni a vezérlést a hibakezelőnek.
Ha kiürítjük a stacket, és nem teszünk mást, akkor a leglátványosabb eredmény egy memóriatúlcsordulás, mivel a lokális, összetett változókat
(sztring, tömb) nem szabadítottuk fel. Szóval, mivel az objektum orientált nyelvekben találunk minden adattípushoz destruktor függvényeket, a
fordítóprogramok készítői azt mondták: létrehozunk egy speciális taszkot, ami az összes destruktor függvény után végrehajt egy szemétgyűjtést.
Ez megoldja a probléma könnyebbik felét, de a nehezebbet nem. Ugyanis, amikor a vezérlés átkerül a hibakezelőhöz, az azt is jelenti, hogy
kilépünk minden belső függvényből, tehát mi lenne ha:
var Sem s
function trouble
s request
foo
s release
Ha a hiba "foo"-ban lép fel, akkor nagy bajban vagyunk, mert az "s" szemafor nem szabadul fel.
A válasz: nem szabad direkt lockolni a szemafort, hanem inkább használjunk egy metódust, ami meghívja az objektumot, amely meghívja a lock-ot,
és el is fogja engedni, ha az objektum megsemmisül.
Tehát egy tisztán objektum orientált nyelvet kell használni, ami azt jelenti, hogy használhatatlan és lassú kódot hoz létre.
Most képzeljük el, hogy egy párhuzamos rendszeren szeretnénk több szálon futtatni egy SMP számítógépen. Ekkor, ha konzisztensek maradunk,
akkor egy hiba esetén minden futó szálat meg kell állítani.
Sajnos ez a szemlélet olyan programokhoz vezetett, amelyek mindig működni fognak, de örökre bug-osak maradnak.
Nézzük a Pliant működését: amikor fellép a hiba, mi regisztráljuk azt, majd folytatjuk, azaz minden belső függvény és a hibakezelő is fut
tovább. Addig, amíg rendesen le nem fut vagy olyan részhez nem ér, amiben ez áll: ha eddig a pontig történt valamilyen hiba, akkor innen
biztonságosan visszaléphetsz.
A hátrány az, hogy átugrani a hibáról a hibakezelőre sok időt vesz igénybe, de mivel a hibakezelő egy kivételkezelő esemény, kit zavar?
Másrészt viszont kevésbé lesznek bug-osak a programjaink.
Pliant-ben néhány hiba fatálisnak bizonyul, ami azt jelenti, hogy nem lép fel hibakezelő esemény. Az egyik legfontosabb ezek közül a
„nincs elég memória”. Ezért nem folytatja a futást ettől a hibától, mert:
- 1. Ha a "nincs elég memória" olyan hibát generálna, amelytől még futhatna tovább, attól még a legbelső utasítások okozhatnak hibát,
mint mondjuk két sztring összefűzése. Azt szerettem volna, ha a hibakezelés megmaradna magas szinten, mivel időt vesz igénybe.
- 2. Nem futtathatjuk biztonságosan a hibakezelőt, mivel neki is szüksége lehet memóriára ideiglenes objektumok részére.
- 3. A korszerű operációs rendszert megbolondíthatja, mivel minden idejét arra használná, hogy kitisztítsa a virtuális memóriát, hogy új
lapokat foglalhasson. Végül a Pliant nyelv hibakezelő tulajdonságainak bevezetésének lezárásaként azt mondhatom, hogy valójában a Pliant
programok akár mind a három módszert is használhatják, de még így sem lesznek tökéletesek.
Kidolgozásra vár.