Useiden asiakkaiden käsittely
select ja poll.
Useiden asiakkaiden käsittely on ilmainen C Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu C Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C Academy-kurssilla on yhteensä 4 oppituntia.
Samanaikaisuuden ongelma
Yksinkertainen palvelin käsittelee yhden asiakkaan kerrallaan. Jos asiakas on hidas, kaikki muut joutuvat odottamaan. Jotta voitte palvella useita asiakkaita samanaikaisesti, tarvitsette toisenlaisen mallin.
Samanaikaisuuden toteutustavat
Kolme yleistä strategiaa:
- Säie tai prosessi asiakasta kohti: yksinkertainen, mutta raskas suuressa mittakaavassa
- Syötteen ja tulosteen multipleksointi komennolla
selecttaipoll: yksi säie tarkkailee useita socket-yhteyksiä - Tapahtumasilmukat komennoilla
epoll/kqueue: skaalautuvat tuhansiin yhteyksiin
Mitä select tekee
select() tarkkailee tiedostokuvaajien joukkoa ja ilmoittaa, mitkä niistä ovat valmiita lukemista tai kirjoittamista varten tai joissa on virheitä – kaikki yhdellä estävällä kutsulla. Näin yksi säie voi palvella useita socket-yhteyksiä.
fd_set-perusteet
select käyttää fd_set-bittimaskia. Hallitkaa sitä makroilla FD_ZERO, FD_SET, FD_CLR ja FD_ISSET.
#include <sys/select.h>
void setup_set(fd_set *set, int listen_fd) {
FD_ZERO(set); /* clear all */
FD_SET(listen_fd, set); /* watch the listener */
}select-kutsun tekeminen
select tarvitsee suurimman tiedostokuvaajan arvon plus yhden ja muokkaa joukkoa paikallaan merkitäkseen valmiit kuvaajat. Koska kutsu tuhoaa joukon alkuperäisen sisällön, joukko on rakennettava uudelleen ennen jokaista kutsua.
#include <sys/select.h>
#include <stdio.h>
int wait_ready(int maxfd, fd_set *read_set) {
int n = select(maxfd + 1, read_set, NULL, NULL, NULL);
if (n < 0) perror("select");
return n; /* number of ready fds */
}select-palvelimen silmukka
Toimintamalli on seuraava: rakentakaa joukko uudelleen, kutsukaa select-komentoa ja käsitelkää sitten jokainen valmis tiedostokuvaaja. Jos kyseessä on kuuntelija, hyväksykää uusi asiakas; jos kyseessä on asiakas, lukekaa dataa.
#include <sys/select.h>
void loop_skeleton(int listen_fd, fd_set *master, int maxfd) {
fd_set work;
for (;;) {
work = *master; /* copy, select destroys it */
select(maxfd + 1, &work, NULL, NULL, NULL);
for (int fd = 0; fd <= maxfd; fd++) {
if (!FD_ISSET(fd, &work)) continue;
/* fd == listen_fd -> accept; else -> recv */
}
}
}Asiakkaiden seuranta
Kun hyväksytte uuden yhteyden, lisätkää sen tiedostokuvaaja pääjoukkoon ja päivittäkää maxfd. Kun asiakas katkaisee yhteyden (recv palauttaa arvon 0), sulkekaa se komennolla close ja poistakaa se joukosta komennolla FD_CLR.
#include <sys/select.h>
#include <unistd.h>
void add_client(fd_set *master, int *maxfd, int conn) {
FD_SET(conn, master);
if (conn > *maxfd) *maxfd = conn;
}
void drop_client(fd_set *master, int conn) {
close(conn);
FD_CLR(conn, master);
}select-komennon rajoitukset
select-komennolla on haittapuolia:
- Rajoitettu
FD_SETUP-tiedostokuvaajien määrään (usein 1024) - Kaikki tiedostokuvaajat käydään läpi O(n)-ajassa jokaisella kutsulla
- Joukko rakennetaan uudelleen jokaisella kierroksella
Monien yhteyksien tapauksessa poll tai epoll skaalautuu paremmin.
Mitä poll tarjoaa
poll() käyttää kiinteän bittimaskin sijaan struct pollfd-rakenteiden taulukkoa. Siksi siihen ei liity 1024 tiedostokuvaajan rajoitusta eikä se tuhoa syötettä jokaisella kutsulla.
#include <poll.h>
void setup_poll(struct pollfd *pfd, int listen_fd) {
pfd[0].fd = listen_fd;
pfd[0].events = POLLIN; /* notify when readable */
}poll-kutsun tekeminen
poll estää suorituksen, kunnes vähintään yksi tiedostokuvaaja on valmis tai aikakatkaisu laukeaa, ja asettaa sen jälkeen revents-kentän jokaiselle valmiille alkiolle.
#include <poll.h>
#include <stdio.h>
int poll_ready(struct pollfd *pfds, int count) {
int n = poll(pfds, count, -1); /* -1 = block forever */
if (n < 0) perror("poll");
return n;
}Skaalaaminen: epoll
Tuhansien yhteyksien tapauksessa Linuxin epoll ja BSD:n kqueue palauttavat vain valmiit tiedostokuvaajat O(1)-ajassa tapahtumaa kohti. Näin vältetään koko joukon läpikäynti, jonka select ja poll tekevät.
Pikatarkistus
Testatkaa useiden asiakkaiden käsittelyä koskeva ymmärryksenne.
Kertaus
Opitte palvelemaan useita asiakkaita yhdellä säikeellä.
selecttarkkailee useita tiedostokuvaajia; hallitkaa niitä FD_-makroilla- Rakentakaa joukko uudelleen jokaisella silmukalla, koska select tuhoaa sen
- Lisätkää hyväksytyt asiakkaat joukkoon ja poistakaa ne yhteyden katketessa
pollvälttää 1024 kuvaajan rajoituksen;epollskaalautuu tuhansiin
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
- 39
- Oppitunnit
- 144
Usein kysytyt kysymykset
Onko oppitunti ”Useiden asiakkaiden käsittely” ilmainen?
Kyllä – oppitunnin ”Useiden asiakkaiden käsittely” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko C Academy-kurssin, päivitä CoddyKit PROhon. C Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Useiden asiakkaiden käsittely”?
select ja poll. 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 4/4.
Kuinka kauan ”Useiden asiakkaiden käsittely”-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
- Pistokkeiden yleiskatsaus
- TCP-palvelin
- TCP-asiakas
- Useiden asiakkaiden käsittely