Az Io aktorokat használ a párhuzamossághoz. Egy aktorra úgy gondolhatunk, mint egy objektumorientált szálra. Az Io-ban bármelyik Object (vagy leszármazottja) küldhet egy aszinkron üzenetet egy @ vagy @@ jelet helyezve az üzenet neve elé. Például:
result := self foo // normális, szinkron üzenetküldés future := self @foo // aszinkron üzenetküldés, azonnal visszatér egy Future objektummal self @@foo // aszinkron üzenetküldés, azonnal visszatér Nil objektummalAmikor egy objektum egy aszinkron üzenetet kap, a várakozási sorába helyezi, és ha még nincs neki egy, elindít egy szálat (egy korutint), hogy feldolgozza az üzeneteket a sorban. A sorban álló üzeneteket szekvenciálisan, FIFO (first-in-first-out) sorrendben dolgozza fel. A vezérlés átengedhető más korutinoknak a yield() hivásával. Például:
obj1 := Object clone obj1 test := method(for(n, 1, 3, n print; yield)) obj2 := obj1 clone obj1 @@test; obj2 @@testEz az "112233" sorozatot fogja kiírni.
Íme, egy sokkal gyakorlatiasabb példa a párhuzamosságra:
HttpServer handleRequest := method(aSocket,Vezérlés átengedése
Egy Object automatikusan lemond a vezérlésről két, a sorában várakozó aszinkron üzenet feldolgozása között. A yield() metódust csak abban az esetben kell használni,, ha a vezérlés átengedésére egy aszinkron üzenet feldolgozása alatt van szükség. További részletekért és eljárásokért lásd az Object primitív párhuzamos metódusait!
Future
Egy "@" jelű aszinkron üzenet eredménye hozzáférhető a visszatérő Future objektum value() metódusát használva:
future isReady // Nem Nil-lel tér vissza, ha az érték kész van result := future value // az aktuális korutin szünetel, amíg az érték készen nem állEz felfüggeszti az aktuális korutint, amíg az aszinkron üzenet fogadója fel nem dolgozta az üzenetet.
Automatikus holtpont detektálás
Egy előnye a Future objektumok használatának, hogy amikor egy value() metódus meghívódik és felfüggesztésra van szükség, az objektum ellenőrizni fogja, hogy a szüneteltetés okozhat-e holtpontot. Egy "Io.Future.value" kivétel váltódik ki, ha a művelet holtpontot okozhat.
sendResultTo()
Lehetőség van arra is, hogy elküldjük az eredményt egy adott objektumnak, amikor elkészült:
object @(foo) sendResultTo(otherObject, "methodName")Egy példa ennek használatára:
pages := List clone urls foreach(i, url, URL clone setUrl(url) @(load) sendResultTo(pages, "add"))Szemétgyűjtés
Még ha egy objektumra már nem is hivatkoznak, nem fog felszabadulni mindaddig, amíg az üzenetsora ki nem ürül, a benne lévő üzeneteket fel nem dolgozza.
Az @ és @@ operátorok
Az @ vagy @@ használata egy aszinkron üzenet előtt csak egy normális operátorüzenet alkalmazása. Tehát a
self @testa következőképpen értelmeződik (és írható is ebben a formában.):
self @(test)Hatékonyság
Egy Object korutinja és üzenetsora felszabadul, ha a sor kiürül és új jön létre, ha egy új aszinkron üzenetet kap. Ezzel elkerüli a pazarló memóriahasználatot abban a tipikus esetben, amikor a legtöbb objektum a rendszerben inaktív állapotban van.
Platformfüggőség
A korutin kód tartalmaz pár sornyi platformspecikus kódot, de jó néhány platformot támogat a rendszer.