Eiffel-ben a párhuzamosságot csupán a legutóbbi, 4-es verzióban vezették be, tehát eredetileg nem kifejezetten párhuzamos programozáshoz tervezték a nyelvet. Ennek ellenére a rájuk jellemző egyszerűséggel és eleganciával oldották meg ezt a bonyolultnak látszó kérdést.
Mint később látni fogjuk, az Eiffel-beli párhuzamosság nem kötődik semmiféle előre definiált párhuzamos architektúrához. Saját belső felépítéséhez igazodik inkább, így nem korlátozzák alkalmazásait ilyen jellegű előfeltételek. Tetszőlegesen leképezhető a fizikai architektúrára, és megvalósító vele a párhuzamosság bármelyik formája (multithreading, kliens-szerver, elosztott programozás, stb).
Eiffel-ben a párhuzamosság megvalósításához elegendő volt egyetlen új kulcsszó bevezetése: ez a separate
. A párhuzamosság többi részét tulajdonképpen a már korábban is létező nyelvi elemek szemantikájának megváltoztatásával valósították meg. A separate
egy minősítő kulcsszó, mellyel egy osztályt illethetünk definiáláskor (a class
kulcsszó előtt), vagy egy különálló objektumot, deklarációjakor. (Ebben az értelemben használata hasonlít az expanded
kulcsszó alkalmazásaira.) Ebből az is következik, hogy Eiffel-ben az objektumon belüli párhuzamosság nem valósítható meg. (Ld. még OOP.)
Példa:
Minden párhuzamos környezetben alapvető szükség van a szinkronizáció problémáinak megoldására. Eiffel-ben ezt a kérdést is nagyon egyszerűen oldották meg.
BUFFER
osztály separate
-ként volt definiálva, a require
rész nem helyességbizonyítási eszközként szolgál, hanem a várakozási feltétel szerepét tölti be: az oldest
függvényt hívó kliens addig fog várakozni, amíg a feltételként megadott állítás igazzá nem válik (és a q
objektum fel nem oldódik egy esetleges korábbi kölcsönös kizárás alól).
Annak egyébként sem lenne túl sok értelme, ha a require
utáni feltételt helyesség szempontjából vizsgálnánk, hiszen a hívó fél a párhuzamos környezet miatt nem tudna felelni a teljesítéséért (a feltétel vizsgálata és a rutin hívása között eltelt időben akár meg is változhat az objektum állapota). Így az egyetlen értelmes megoldás csak az lehet, ha a megadott állítást belépési feltételnek tekintjük, melynek teljesülnie kell a művelet végrehajtása előtt. (Ld. még helyességbizonyítás.)
Ritka esetben szükség lehet arra, hogy egy fontos (VIP) kliens elvegye egy kölcsönös kizárással kezelt objektum elérését az azt éppen használó másik objektumtól. Ezt persze nem lehet minden jelzés nélkül megtenni, hiszen ez a módszer inkonzisztens állapotba hozhatja a résztvevő objektumokat. Ezért erre azt a megoldást dolgozták ki az Eiffel fejlesztői, hogy az eredeti hívóban kivételt váltanak ki, ezzel jelezve azt, hogy megfelelően korrigálja jelenlegi állapotát.
Erre külön könyvtári osztályt biztosít a konkurens Eiffel. Természetesen arra is lehetőség van, hogy a korábbi hívó ne adja át a kezelt objektum elérését. Ekkor az elérést átvenni akaró objektumban váltódik ki a kérdéses kivétel. Egy kevésbé agresszív megoldás az, hogy ha a második hívó nem tudja megszerezni az elérést, akkor várakozó állapotba kerül, és kivárja, amíg az első hívó befejezi tevékenységét, és megszünteti a kezelt objektum zároltságát.
A demand
utasítás szolgál a zár elkérésének bejelentésére, a yield
a zár átengedésére, az insist
pedig várakozásos elkérés bejelentésére.
Az Eiffel-ben megírt logikailag párhuzamos programok fizikai párhuzamos eszközökre való leképzéséhez egy új file-típust vezettek be a nyelv fejlesztői: ez a Concurrency Configuration File (CCF). Ez a file nem tartozik közvetlenül a párhuzamos programhoz, és különböző rendszerekben különbözőképpen képezheti le ugyanazt a konkurens Eiffel-ben írt szoftvert. Az aktuális leképzési mód futás közben is lekérdezhető és módosítható a párhuzamos programon belül.