Please download to get full document.

View again

of 21
All materials on our website are shared by users. If you have any questions about copyright issues, please report us to resolve them. We are always happy to assist you.

I/O Multiplexing select() e poll()

Category:

Food

Publish on:

Views: 6 | Pages: 21

Extension: PDF | Download: 0

Share
Related documents
Description
I/O Multiplexing select() e pll() Crs di laurea in Infrmatica Labratri di Reti di Calclatri A.A Simne Bassis Labratri di Reti di Calclatri (Infrmatica) - A.A Università
Transcript
I/O Multiplexing select() e pll() Crs di laurea in Infrmatica Labratri di Reti di Calclatri A.A Simne Bassis Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI Mdelli di I/O Mdelli di I/O Blcking I/O Nnblcking I/O Quand un perazine di I/O nn può essere cmpletata senza mettere il prcess in pausa, nn l si mette in pausa, ma si ritrna un errre I/O multiplexing (select() e pll()) Il prgramma si blcca in una call a select(), ma è in grad di gestire più canali Signal driven I/O (SIGIO) Il prgramma nn si blcca mai, ma deve gestire pprtunamente i segnali in arriv dal kernel Asynchrnus I/O (psix.1 ai_ functins) Cme spra, ma il kernel nn ci avvisa quand una perazine di I/O può essere iniziata, bensì quand è terminata È l unica mdalità effettivamente asincrna (il prcess nn viene mai blccat) Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 473 1 Mdelli di I/O I/O multiplexing serve quand un hst deve gestire all stess temp descrittri multipli (scket e input) Scket multiple Listening scket e cnnected scket TCP e UDP scket Servizi e prtclli multipli Due fasi distinte per le perazini di input 1. Attesa che i dati sian dispnibili 2. Cpia dei dati dal kernel al prcess Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 474 Blcking I/O applicazine kernel recvfrm() System call Nessun dispnibile Attendi i dati Il prcess si blcca ad una call a recvfrm() dispnibile cpia in crs ricezine Return OK cpia cmpleta Cpia i dati dal kernel all utente Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 475 2 NnBlcking I/O applicazine kernel recvfrm() System call EWOULDBLOCK Nessun dispnibile Il prcess chiama ripetutamente recvfrm() attendend di ricevere i dati (plling) recvfrm() recvfrm() System call EWOULDBLOCK System call Nessun dispnibile dispnibile cpia in crs Attendi i dati Cpia i dati dal kernel all utente ricezine Return OK applicazine Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 476 I/O Multiplexing select() e pll() applicazine kernel Il prcess si blcca ad una call a select() attendend che una delle pssibili scket diventi dispnibile in lettura select() recvfrm() System call return readable System call Nessun dispnibile dispnibile cpia in crs Attendi i dati Il prcess si blcca mentre i dati vengn cpiati nell applicatin buffer ricezine Return OK cpia cmpleta Cpia i dati dal kernel all utente Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 477 3 Signal driver I/O SIGIO applicazine kernel Il prcess cntinua l esecuzine Attivazine SIGIO Signal Handler Sigactin System call return Nessun dispnibile Attendi i dati Il prcess si blcca mentre i dati sn cpiati nell applicatin buffer Signal Handler recvfrm() ricezine invi SIGIO System call Return OK dispnibile cpia in crs cpia cmpleta Cpia i dati dal kernel all utente Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 478 Asynchrnus I/O applicazine kernel ai_read() System call Nessun dispnibile return Attendi i dati Il prcess cntinua l esecuzine dispnibile cpia in crs Signal handler ricezine Invia segnale specificat in ai_read() cpia cmpleta Cpia i dati dal kernel all utente Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 479 4 Cnfrnt tra i mdelli di I/O blcking nnblcking I/O multiplexing signal-driven I/O asynchrnus I/O initiate check check initiate check check check blcked Attesa dati check check ready initiate ntificatin initiate cmplete blcked cmplete blcked cmplete blcked cmplete ntificatin Cpia dati dal kernel all utente 1 fase trattata differentemente, 2 fase trattata all stess md Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI Gestisce entrambe le fasi 480 Blcking vs Nnblcking Di default le scket sn blccanti Quand una syscall nn può essere cmpletata immediatamente, il prcess viene sspes attendend che sia cmpletata Quattr categrie di system call blccanti Operazini di input: read, readv, recv, recvfrm, e recvmsg Blcking: sleep finchè i dati nn sn dispnibili (almen 1 byte per TCP e un per UDP) Nnblcking: ritrn immediat cn errre EWOULDBLOCK Operazini di utput: write, writev, send, sendt, e sendmsg Blcking: sleep per TCP scket se l spazi nel buffer di invi nn è sufficiente Nnblcking: se nn c è spazi nel buffer di invi, ritrn immediat cn errre EWOULDBLOCK. Se l spazi è parziale, ritrna il numer di byte cpiati (shrt cunt) Nta: UDP nn ha send buffer. Un perazine di utput nn è mai blccante La funzine accept Blcking: sleep finchè si rende dispnibile una cnnessine Nnblcking: ritrn immediat cn errre EWOULDBLOCK La funzine cnnect (sl per TCP) Blcking: sleep finchè la cnnessine è instaurata Nnblcking: ritrn immediat cn errre EINPROGRESS se la cnnessine è in crs Nta: la cnnect per UDP nn è un reale three-way handshake Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 481 5 Nnblcking I/O È pssibile creare scket nn blccanti attravers fcntl() Che sta per file cntrl #include unistd.h #include fcntl.h sckfd = scket(pf_inet, SOCK_STREAM, 0); fcntl(sckfd, F_SETFL, O_NONBLOCK); impsta il file status flag al valre specificat da arg ritrna un valre null in cas di success -1 in cas di errre Si tratta di perazini ausiliarie che è pssibile eseguire su un file descriptr che nn riguardan la nrmale lettura e scrittura di dati ma la maniplazine e il cntrll sia delle lr prprietà, che di tutta una serie di ulteriri funzinalità che il kernel può mettere a dispsizine Il prttip di fcntl() dipende dal cmand impartit #include unistd.h #include fcntl.h int fcntl(int fd, int cmd) int fcntl(int fd, int cmd, lng arg) int fcntl(int fd, int cmd, struct flck * lck) Valri di ritrn: diversi a secnda dell'perazine -1 in cas di errre: errn settata cn il relativ cdice errre Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 482 Nnblcking vs I/O Multiplexing In cas di scket nn blccanti Si può interrgare (pll) la scket per ttenere infrmazini Se nn ci sn dati ritrna -1 cn errn settat a EWOULDBLOCK In gni cas busy-waiting nn è una buna strategia Oppure usare la select (Synchrnus I/O Multiplexing) Permette di mnitrare diverse scket all stess temp Avvisand quand alcune sn prnte In lettura In scrittura Hann sllevat eccezini - Da nn cnfndersi cn le Java Exceptin Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 483 6 Megli la select(), ma La select() è un dei metdi più lenti per mnitrare scket Esistn diverse alternative, tra cui libevent (http://libevent.rg/) I meccanismi interni sn cmpletamente indipendenti dalle API espste Supprta kqueue, event prts, POSIX select(), Windws select(), pll e epll Permette l svilupp di applicazini prtabili E dispnibile per piattafrme Linux, *BSD, Mac OS X, Slaris, Windws, Frnisce il meccanism di ntifica di eventi tutt ra più scalabile Può essere usat per applicazini multi-thread Island i singli eventi csì che un singl thread ne abbia access Cntrlland gli accessi a eventi cndivisi Frnisce un meccanism sfisticat per I/O di rete bufferizzat Cn supprt per scket, filtri, limitazini sul rate, SSL, Include il supprt di diversi utili prtclli ( DNS, HTTP, RPC, ) Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 484 #include sys/time.h #include sys/types.h #include unistd.h select() e fd_set int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeut); La select() mnitra insiemi (set) di descrittri di file readfds: per vedere se si può leggere da un fd es. per leggere da stdin e da sckfd, basta aggiungere 0 e sckfd al set readfds writefds: idem per scritture exceptfds: per verificare l esistenza di eccezini un eccezine nn è un errre (ad es., l arriv di dati urgenti ut-f-band) numfds deve essere pst pari a fd max + 1 fd max è il fd più grande cntrllat In linux cn il cmand sysctl fs.file-nr si ttiene il massim numer di fd che pssn essere aperti Al ritrn viene restituit il numer di descrittri prnti risultan prnti Macr readfds, writefds e exceptfds sarann mdificati per riflettere quali tra gli fd selezinati Per frtuna esistn macr per perare sugli insiemi di tip fd_set Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI FD_SET(int fd, fd_set *set); FD_CLR(int fd, fd_set *set) FD_ISSET(int fd, fd_set *set) FD_ZERO(fd_set *set) FD_COPY(fd_set *fdset_rig, fd_set *fdset_cpy); Nn è definit in tutte le piattafrme, ma è semplice definire una macr usand memcpy Descrizine Aggiunge fd a set Rimuve fd dal set Ritrna ver se fd è in set Pulisce tutte le entry da set Cpia un fd set 485 7 select() e struct timeval struct timeval permette di specificare un timeut All scadere, se nessun fd è prnt, la select() ritrna struct timeval { int tv_sec; int tv_usec; ; // secndi // micrsecndi Al ritrn timeut ptrebbe essere aggirnata per mstrare quant temp manca fin all scadere del timeut Dipende dalla versine di Unix Settand struct timeval a 0, frza la select() a trnare immediatamente (timeut immediat) Serve per fare plling su tutti i fd nel set Settand struct timeval a NULL, frza la select() a nn andare mai in timeut Serve per attendere finchè un fd nel set è prnt E pssibile evitare di mnitrare un cert set, mettendl a NULL Fate attenzine: nn fate affidament sul cmput del temp (sprattutt in micrsecndi) Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 486 Descrittri prnti In lettura Il numer di byte di dati nel buffer di ricezine è più grande di lw-water mark Settabile cn l pzine SO_RCVLOWAT Di slit pari a 1 byte la cnnessine è chiusa in lettura In una listening scket il numer di cnnessini cmpletate è maggire di 0 C è un errre pendente In scrittura Il numer di byte dispnibili nel buffer di invi è più grande di lw-water mark Settabile cn l pzine SO_SNDLOWAT Di slit pari a 2048 byte La cnnessine è chiusa in scrittura C è un errre pendente Eccezini pendenti Quand esistn dati ut-f-band per la scket Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 487 8 Un semplice esempi #include stdi.h #include sys/time.h #include sys/types.h #include unistd.h #define STDIN 0 int main(vid) { struct timeval tv; fd_set readfds; tv.tv_sec = 2; tv.tv_usec = ; FD_ZERO(&readfds); FD_SET(STDIN, &readfds); // dn't care su writefds e exceptfds: select(stdin+1, &readfds, NULL, NULL, &tv); if (FD_ISSET(STDIN, &readfds)) printf( E stat premut un tast!\n ); else printf( timeut!\n ); return 0; Questini di prtabilità: dipende dalla piattafrma in us: L us della select() cn datagram scket L update del temp rimanente prima del timeut in struct timeval Megli nn affidarsi a tal valre se si vule che la prpria applicazine sia prtabile Ptete usare gettimefday() Una scket in asclt cn listen() va aggiunta al set readfds Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 488 Select e scket inizializzazine fd_set master; // master file descriptr list fd_set read_fds; // temp file descriptr list per la select() int fdmax; // max file descriptr FD_ZERO(&master); // svuta master e temp sets FD_ZERO(&read_fds); Servn master e temp set perché la select() mdifica il temp set mstrand quali fd sn prnti gestine scket passiva if (listen(listener, 10) == -1) { perrr( listen ); exit(3); // si aggiunge listener al set master FD_SET(listener, &master); // mantiene memria del fd più grande fdmax = listener; // finra è quest Ogni nuva cnnessine va aggiunta al master set Csì cme gni chiusura necessita della rimzine dell fd dal master set Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 489 9 Select e scket main lp: passive scket fr(;;) { FD_COPY(&master, &read_fds); // cpia del master set if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { perrr( select ); exit(4); Per questini di prtabilità megli usare FD_COPY piuttst che assegnare master a read_fds // si cicla per verificare quale fd è prnt per la lettura fr(i = 0; i = fdmax; i++) { if (FD_ISSET(i, &read_fds)) { // l i-esim fd è prnt!! if (i == listener) { // nuva cnnessine in arriv addrlen = sizef remteaddr; newfd = accept(listener, (struct sckaddr *)&remteaddr, &addrlen); if (newfd == -1) { perrr( accept ); else { FD_SET(newfd, &master); if (newfd fdmax) { fdmax = newfd; // si aggiunge il nuv fd al master set // e si aggirna il max fd Può essere utile definire una macr MAX(a,b) Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 490 Select e scket main lp: active sckets else { // un client ha inviat un messaggi if ((nbytes = recv(i, buf, sizef buf, 0)) = 0) { if (nbytes == 0) { // cnnessine chiusa printf( selectserver: scket %d hung up\n , i); else { perrr( recv ); // errre cnnessine chiusa dal client Ricrdarsi di fare pulizia sul master clse(i); FD_CLR(i, &master); // un p di pulizia: chiusura scket e // rimzine fd dal set Per rendere più efficiente il cicl ricrdarsi di mdificare fdmax else { // sn stati ricevuti dati dal client // ********* // prtcl specific part // *********. Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI Select lat client Esempi: Si leggn le single linee da file e le si invia al server che prvvederà a ritrnarle vid str_cli(file *fp, int sckfd) { int maxfdp1; fd_set rset; char sendline[maxline], recvline[maxline]; FD_ZERO(&rset); fr ( ; ; ) { FD_SET(filen(fp), &rset); FD_SET(sckfd, &rset); maxfdp1 = max(filen(fp), sckfd) + 1; Select(maxfdp1, &rset, NULL, NULL, NULL); if (FD_ISSET(sckfd, &rset)) { /* scket is readable */ if (readline(sckfd, recvline, MAXLINE) == 0) perrr( str_cli: server terminated prematurely ); fputs(recvline, stdut); if (FD_ISSET(filen(fp), &rset)) { /* input is readable */ if (fgets(sendline, MAXLINE, fp) == NULL) return; /* all dne */ write(sckfd, sendline, strlen(sendline)); Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI La funzine filen() asscia il desecrittre di file a un stream Suppnend l esistenza della funzini readline() che in realtà nn esiste! Ma che sappiam implementare cn fgets Prblema: se si arriva a fine file, l applicazine termina, anche se ci pssn essere dati sulla scket. Per avere più cntrll è pprtun usare shutdwn() 492 Select lat client vid str_cli(file *fp, int sckfd) { int maxfdp1, fileef; fd_set rset; char sendline[maxline], recvline[maxline]; if (FD_ISSET(filen(fp), &rset)) { /* input is readable */ if (fgets(sendline, MAXLINE, fp) == NULL) { fileef = 1; shutdwn(sckfd, SHUT_WR); /* send FIN */ FD_CLR(filen(fp), &rset); cntinue; stdinef = 0; FD_ZERO(&rset); fr ( ; ; ) { if (fileef == 0) FD_SET(filen(fp), &rset); FD_SET(sckfd, &rset); maxfdp1 = max(filen(fp), sckfd) + 1; Select(maxfdp1, &rset, NULL, NULL, NULL); write(sckfd, sendline, strlen(sendline)); 2 if (FD_ISSET(sckfd, &rset)) { /* scket is readable */ if (readline(sckfd, recvline, MAXLINE) == 0) { if (fileef == 1) return; /* nrmal terminatin */ else perrr( str_cli: server terminated prematurely ); fputs(recvline, stdut); 1 Sluzine: cn shutdwn() viene inviat il segment FIN alla cntrparte che dp aver inviat tutti i dati terminerà cn il su FIN Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI select() vs. pll() Stria select() intrdtta nel 1983 in 4.2BSD Unix (BSD) pll() intrdtta nel 1986 in SVR3 Unix (System V) In linux nel 1997 Funzinalità: le stesse, cambian i dettagli select() svrascrive gli fd_set indicand quali fd sn prnti; pll() nn mdifica i dati in input pll() gestisce mlti fd (anche più di 1024) senza grssi prblemi; select() usa bitmask di taglia fissata ed è men cnveniente su alcuni sistemi per supprtare più di 1024 fd è necessari mdificare FD_SETSIZE pll() gestisce più tiplgie di eventi ma ai fini pratici nn sn rilevanti diversi valri di timeut: pll() cnsidera millisecndi, select() un struct timeval Entrambe incraggian un apprcci lp-style e nn event-based Velcità: la stessa, incredibilmente lenta (megli librerie eventbased) select() frza una scansine dei primi fd max file descriptr; la pll() n (una piccla vittria per la pll()) select() usa 4 bit di dati per fd, mentre la pll() ne usa 64 bits per fd (una piccla vittria per la select() se pensate alla cpia dei dati in kernel space) Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 494 select() vs. pll() Prtabilità select () Esiste da parecchi ed è presente dappertutt. Un prblema cn gli fd_set: nn si sa quand si verifica verflw sulla bitmask (nn si può verificare l FD_SETSIZE in md prtabile) Mlte versini di Unix permettn di ridefinire FD_SETSIZE a cmpile time, ma nn Linux L include header richiest per l fd_set varia da sistema a sistema Alcuni sistemi mdifican l struct timeval. In tali casi se si ripete la select() si ha bisgn di inizializzare ad gni cicl il timeut pll() Nn esiste su vecchie versini di Unix su Windws pre-vista. Su alcune versini di Mac OS X la versine è buggata. La maggir parte delle prime implementazini wrappan la select() Il md di settare bit è specificat nell standard, ma varia tra implementazini diverse Cmplessità Tutte le funzini event-driven rendn il cdice mlt più cmpless e difficile da seguire rispett all us di select() e pll() Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI pll() # include sys/pll.h int pll(struct pllfd fds[ ], nfds_t nfds, int timeut); struct pllfd fds[ ]: gni entry cntiene tipicamente int fd: indica quale fd mnitrare shrt events: una bitmap che rappresenta gli eventi da mnitrare È pssibile usare tramite OR ( ) le seguenti macr POLLIN: dati prnti per recv() POLLOUT: dati prnti per send() POLLRDNORM: recv() di dati nrmali POLLWRNORM: dati nrmali prnti per send() POLLRDBAND: recv() di dati pririty band POLLPRI: recv() di dati high pririty POLLWRBAND: send() di dati pririty band shrt revents: una bitmap che rappresenta quali eventi si sn verificati Oltre ai precedenti, è pssibile usare POLLERR: errre POLLHUP: scket chiusa dalla cntrparte POLLNVAL: prblemi cn il scket descriptr nfds_t nfds: numer di fd settati in fds[ ] int timeut: espress in millisecndi se negativ si attende all infinit se 0 ritrna immediatamente Il valre di ritrn indica su quanti fd si è verificat un event 0 in cas di timeut -1 in cas di errre Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 496 Cndizini per revents POSIX lascia mlti buchi nelle sue definizini Tutti i dati TCP reglari e UDP sn cnsiderati nrmali Dati TCP ut-f-band sn pririty band Cnnessini chiuse in lettura sn cnsiderate dati nrmali La read() seguente ritrnerà 0 La presenza di errri può essere cnsiderata un dat nrmale un errre La read() seguente ritrnerà -1 La dispnibilità di una nuva cnnessine su una listening scket può essere cnsiderata un dat nrmale pririty data Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI pll() int s1, s2; int rv; char buf1[256], buf2[256]; struct pllfd ufds[2]; s1 = scket(pf_inet, SOCK_STREAM, 0); s2 = scket(pf_inet, SOCK_STREAM, 0); // suppniam di essere cnnessi ad un server // cnnect(s1,...)... // cnnect(s2,...)... // si setta l array dei file descriptrs // // in quest esempi, ci accntentiam di distinguere se // ci sn dati dati ut-f-band prnti per una recv() // check per dati nrmali ut-f-band ufds[0].fd = s1; ufds[0].events = POLLIN POLLPRI; // check sl per dati nrmali ufds[1].fd = s2; ufds[1].events = POLLIN; Labratri di Reti di Calclatri (Infrmatica) - A.A Università di Milan DI 1 // attendi il verificarsi di eventi sulla scket // cn 3.5 secndi di timeut rv = pll(ufds, 2, 3500); if (rv == -1) { perrr( pll ); else if (rv == 0) { printf( timeut!\n ); else { // cntrlla se ci sn eventi su s1: if (ufds[0].revents & POLLIN) { recv(s1, buf1, sizef buf1, 0); // dati nrmali if (ufds[0].revents & POLLPRI) { // dati ut-f-band recv(s1, buf1, sizef buf1, MSG_OOB); // cntrlla se ci sn eventi su s2: if (ufds[1].revents & POLLIN) { recv(s1, buf2, sizef buf2, 0); Oltre pll() e select() Alternative event-driven più mderne, nn standardizzate epll: Linux kqueue: FreeBSD, NetBSD, OpenBSD, Darwin /dev/pll: Slaris, HPUX, pllset: AIX, event Cmpletin: Slaris 10 I/O Cmpletin Prts:
Search Related
We Need Your Support
Thank you for visiting our website and your interest in our free products and services. We are nonprofit website to share and download documents. To the running of this website, we need your help to support us.

Thanks to everyone for your continued support.

No, Thanks