Asynkroninen I/O epollilla ja kqueuella
Käsittele useita yhteyksiä Linuxin epollilla sekä BSD:n tai macOS:n kqueuella.
Asynkroninen I/O epollilla ja kqueuella on ilmainen C++ Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu C++ Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C++ Academy-kurssilla on yhteensä 4 oppituntia.
Miksi asynkronista I/O:ta?
Yksi säie yhteyttä kohti ei skaalaudu tuhansiin tai miljooniin asiakkaisiin. Asynkronisen I/O:n avulla yksi säie voi käsitellä useita socketteja odottamalla, että jokin niistä tulee luettavaksi tai kirjoitettavaksi.
Linux: epoll
epoll on Linuxin skaalautuva tapahtumarajapinta. Lisätkää tiedostokuvaajat epoll-instanssiin ja odottakaa tapahtumia millä tahansa niistä.
#include <sys/epoll.h>
int epfd = epoll_create1(0);
epoll_event ev{};
ev.events = EPOLLIN;
ev.data.fd = sock;
epoll_ctl(epfd, EPOLL_CTL_ADD, sock, &ev);Tapahtumien odottaminen
epoll_wait estää suorituksen, kunnes tapahtumia on saatavilla, ja palauttaa sitten valmiit tiedostokuvaajat.
epoll_event events[64];
int n = epoll_wait(epfd, events, 64, -1);
for (int i = 0; i < n; ++i) {
int fd = events[i].data.fd;
handle_io(fd);
}Reunatriggaus ja tasotriggaus
Käytettävissä on kaksi tilaa:
- Tasotriggaus (oletus) — epoll ilmoittaa tapahtumasta niin kauan kuin ehto täyttyy
- Reunatriggaus (
EPOLLET) — ilmoittaa vain tilan muuttuessa; socket on tyhjennettävä kokonaan joka kerta
macOS ja BSD: kqueue
kqueue on epollin BSD-vastine, joka on saatavilla myös macOS:ssä. Sen toimintaperiaate on samankaltainen, mutta rajapinta on erilainen.
#include <sys/event.h>
int kq = kqueue();
struct kevent ev;
EV_SET(&ev, sock, EVFILT_READ, EV_ADD, 0, 0, nullptr);
kevent(kq, &ev, 1, nullptr, 0, nullptr);Windows: IOCP
Windows käyttää I/O Completion Ports -tekniikkaa (IOCP), joka perustuu valmistumisesta ilmoittamiseen, kun taas epoll ja kqueue käyttävät valmiusmallia.
Estämättömät socketit
Asettakaa socketit estämättömään tilaan komennolla fcntl(fd, F_SETFL, O_NONBLOCK). Muuten luku- ja kirjoitusoperaatiot voivat estää koko tapahtumasilmukan.
Tapahtumasilmukan malli
Loputtomasti suoritettava silmukka:
- Odottakaa valmiita tapahtumia
- Suorittakaa jokaisen tapahtuman kohdalla I/O-operaatioita, kunnes ne estyisivät
- Toistakaa
Monien asiakkaiden käsittely
Yksi epoll-säie voi käsitellä kymmeniätuhansia samanaikaisia yhteyksiä — tämä on C10K-ongelma. Nykyaikaiset järjestelmät yltävät miljooniin yhteyksiin.
Yleiset sudenkuopat
Varokaa seuraavia ongelmia:
- Estämättömän tilan asettamisen unohtaminen
- Reunatriggaus ilman socketin tyhjentämistä
- Suljettujen tiedostokuvaajien poistamatta jättäminen epoll-joukosta
- Yhteyskohtaiset puskurivuodot
Korkeamman tason kääreet
epoll-silmukan kirjoittaminen käsin on virhealtista. Käyttäkää tuotantokoodissa libuv-, libevent- tai Boost.Asio-kirjastoa — ne piilottavat alustojen väliset erot ja tarjoavat testatut I/O-silmukat.
Asynkroninen I/O vs. säikeet
Asynkroninen I/O skaalautuu paremmin, mutta sitä on vaikeampi kirjoittaa. Muutaman tuhannen yhteyden palvelimissa säie yhteyttä kohti on yksinkertaisempi ratkaisu. Valitkaa malli odotettavissa olevan kuormituksen perusteella.
Pikatarkistus
Miten reunatriggaus ja tasotriggaus eroavat toisistaan epollissa?
Kertaus
Asynkroninen I/O skaalautuu valtavaan samanaikaisuuteen käsittelemällä useita socketteja yhdessä säikeessä. Linux käyttää epollia, BSD ja macOS kqueuea, ja Windows IOCP:tä. Asettakaa socketit estämättömään tilaan. Käyttäkää tuotannossa kirjastoa (Asio, libuv tai libevent) tapahtumasilmukan kirjoittamisen sijaan.
Opi C++ tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 51
- Oppitunnit
- 203
Usein kysytyt kysymykset
Onko oppitunti ”Asynkroninen I/O epollilla ja kqueuella” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa C++ Academy-oppimispolun 3 oppituntia, myös oppitunnin “Asynkroninen I/O epollilla ja kqueuella”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. C++ Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Asynkroninen I/O epollilla ja kqueuella”?
Käsittele useita yhteyksiä Linuxin epollilla sekä BSD:n tai macOS:n kqueuella. Harjoittelet C++ Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni C++ Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin C++ Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.
Kuinka kauan ”Asynkroninen I/O epollilla ja kqueuella”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä C++ Academy-oppitunnilla?
Kyllä. Jokainen C++ Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- BSD Sockets API C++:ssa
- TCP-kaikupalvelimen rakentaminen
- Asynkroninen I/O epollilla ja kqueuella
- Boost Asion käyttö nykyaikaiseen asynkroniseen I/O:hon