( nagylzs | 2017. 10. 29., v – 20:56 )

Necromancer vagyok. :-p

Mi a baj a multi threaddel? Alábbiakban vázolom.

* egy chat alkalmazás akkor jó, ha az üzenetek azonnal, várakozás nélkül átmennek a feladótól a címzetthez
* a kliens a szerver oldalról webes alkalmazás esetén websocket-et használ, esetleg long polling-ot ha muszáj. Desktop/mobil app esetén meg normál socket-et. Mindkét esetre igaz, hogy a kliens kiküldi a kérést, és a kapcsolat megszakítása nélkül várja a választ.
* tehát ha sok a user, akkor a szerveren egyszerre több request is várakozik response-ra. *sok aktív request van egyszerre*

Egy multi threaded szervernél ez azt jelenti, hogy *sok* szál van egyszerre. A sok alatt itt nem azt kell érteni hogy 100, hanem hogy mondjuk 100 ezer. A szálak közötti váltogatás meg olyan context switching-et csinál, hogy a géped akkor is le van terhelve, ha nem csinál semmit. Nem hatékony!

Ezzel szemben az async io-s megoldás minden aktív request-re egy file descriptor-t nyit, és ha senki nem küld üzenetet, akkor a szerver se csinál semmit. Ha bejön az üzenet (alacsony szinten: megszakításból), akkor a kernel beteszi a pufferbe az adatcsomagot, és szól a szervernek hogy itt egy adat, dolgozd föl. Az meg feldolgozza, és kiküld egy másik csomagot annak a kliensnek, aki épp azt várja. Nincsen sok szál csak egy, és ha nincs üzenetváltás, akkor a szerver pihen. Mivel csak egy szál van, ezért nincs shared memory, nincs szükség lock-olásra, nincs context switching stb. És a kódban nincs olyan hogy "jaj még nem jött üzenet várjunk egy kicsit hátha jön", mert minden eseményvezérelt.

Az async io-val írt kód eseményvezérelt. Ez olyan problémák megoldására jó, amiknél eseményeket kell kezelni. A chat tipikusan ilyen. A nagyon sok useres chat meg főleg ilyen.

Konkrétan egy async io-val megvalósított szerver egy gyengécske, több éves vason is simán kiszolgál 100 ezer nyitott kapcsolatot egyszerre. (Feltéve hogy nem beszélget egyszerre az egyik fele a másikkal.) Ha jól van megírva, akkor eközben alig használ memóriát meg CPU-t.

Próbáld meg ugyanezt megvalósítani multi thread-es szerverrel. 100 ezer nyitott kapcsolat az vagy 100 ezer szál, vagy elkezdhetsz ügyeskedni greenlet-ekkel meg microthreads-el, de sosem lesz igazán jó.