C++ Academy · Oppitunti

Asynkroninen I/O epollilla ja kqueuella

Käsittele useita yhteyksiä Linuxin epollilla sekä BSD:n tai macOS:n kqueuella.

Oppitunti 3/414 vaihetta

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:

  1. Odottakaa valmiita tapahtumia
  2. Suorittakaa jokaisen tapahtuman kohdalla I/O-operaatioita, kunnes ne estyisivät
  3. 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.

Aloita maksutta

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

  1. BSD Sockets API C++:ssa
  2. TCP-kaikupalvelimen rakentaminen
  3. Asynkroninen I/O epollilla ja kqueuella
  4. Boost Asion käyttö nykyaikaiseen asynkroniseen I/O:hon
← Takaisin: C++ Academy