Differences

This shows you the differences between two versions of the page.

Link to this comparison view

so:laboratoare:laborator-11 [2015/05/18 00:58]
laura.vasilescu [Exercițiul 1 - poll (1p)]
so:laboratoare:laborator-11 [2022/05/19 16:54] (current)
liza_elena.babu [Înainte de laborator: Feedback]
Line 1: Line 1:
 ====== Laborator 11 - Operații IO avansate - Linux ====== ====== Laborator 11 - Operații IO avansate - Linux ======
- 
-===== Materiale Ajutătoare ===== 
- 
-  * [[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab11-slides.pdf | lab11-slides.pdf]] 
-  * [[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab11-refcard.pdf | lab11-refcard.pdf]] 
  
  
Line 10: Line 5:
  
   * TLPI - Chapter 63, Alternative I/O models   * TLPI - Chapter 63, Alternative I/O models
 +
 +===== Link-uri către secțiuni utile =====
 +==== Linux ====
 +
 +  * [[#​linux_-_multiplexarea_io|Linux - multiplexarea I/O]]
 +    * [[#​select|select]]
 +    * [[#​poll|poll]]
 +    * [[#​epoll|epoll]]
 +  * [[#​linux_-_generalizarea_multiplexarii|Linux - generalizarea multiplexării]]
 +    * [[#​eventfd|eventfd]]
 +    * [[#​signalfd|signalfd]]
 +  * [[#​linux_-_operatii_asincrone|Linux - operații asincrone]]
 +  * [[#​zero-copy_io|Zero-copy I/O]]
 +  * [[#​vectored_io|Vectored I/O]]
 +
 +<​hidden>​
 +===== Înainte de laborator: Feedback =====
 +
 +Pentru a îmbunătăți cursul de SO, componentele sale și modul de desfășurare,​ ne sunt foarte utile opiniile voastre. Pentru aceasta, vă rugăm să accesați și completați formularul de feedback de pe site-ul acs.curs.pub.ro. Trebuie să fiți autentificați și înrolați în cadrul cursului.
 +
 +Formularul este anonim și este activ în perioada 11 mai 2020 - 22 mai 2020. Rezultatele vor fi vizibile în cadrul echipei cursului doar după încheierea sesiunii. Este accesibil la link-ul “Formular feedback” a paginii principale a cursului de SO al seriei voastre pe acs.curs.pub.ro. Nu este în meta-cursul disponibil tuturor seriilor.
 +
 +Vă invităm să evaluați activitatea echipei de SO și să precizați punctele tari și punctele slabe și sugestiile voastre de îmbunătățire a disciplinei. Feedback-ul vostru ne ajută să creștem calitatea materiei în anii următori și să îmbunătățim disciplinele pe care le veți face în continuare.
 +
 +Vom publica la începutul semestrului viitor analiza feedback-ului vostru.
 +
 +Ne interesează în special:
 +
 +  * Ce nu v-a plăcut și ce credeți că nu a mers bine?
 +  * De ce nu v-a plăcut și de ce credeți că nu a mers bine?
 +  * Ce ar trebuie să facem ca lucrurile să fie plăcute și să meargă bine?
 +</​hidden>​
 =====  Linux - multiplexarea I/O ===== =====  Linux - multiplexarea I/O =====
  
Line 56: Line 83:
  
 Dezavantaje:​ Dezavantaje:​
-    * lungimea ​setul de descriptori este definită cu ajutorul lui FD_SETSIZE, și implicit are valoarea ​64;+    * lungimea ​setului ​de descriptori este definită cu ajutorul lui ''​FD_SETSIZE''​, și implicit are valoarea ​1024;
     * este necesar ca seturile de descriptori să fie reconstruite la fiecare apel ''​select'';​     * este necesar ca seturile de descriptori să fie reconstruite la fiecare apel ''​select'';​
     * la apariția unui eveniment pe unul dintre descriptori,​ toți descriptorii puși în set înainte de ''​select''​ trebuie testați pentru a vedea pe care dintre ei a apărut evenimentul;​     * la apariția unui eveniment pe unul dintre descriptori,​ toți descriptorii puși în set înainte de ''​select''​ trebuie testați pentru a vedea pe care dintre ei a apărut evenimentul;​
Line 290: Line 317:
     epoll_wait(epfd,​ &​ret_ev,​ 1, -1);     epoll_wait(epfd,​ &​ret_ev,​ 1, -1);
    
-    if ((rev_ev.data.fd == listenfd && ((ret_ev.events & EPOLLIN) != 0)) {+    if ((ret_ev.data.fd == listenfd&& ((ret_ev.events & EPOLLIN) != 0)) {
         /* TODO ... handle new connection */         /* TODO ... handle new connection */
     }     }
-    else if ((rev_ev.data.fd == STDIN_FILENO &&+    else if ((ret_ev.data.fd == STDIN_FILENO&&
                     ((ret_ev.events & EPOLLIN) != 0)) {                     ((ret_ev.events & EPOLLIN) != 0)) {
         /* TODO ... read user data from standard input */         /* TODO ... read user data from standard input */
Line 310: Line 337:
  
 Pentru a asigura în Linux posibilitatea așteptării de evenimente multiple s-a definit interfața ''​eventfd''​. Cu ajutorul acestei interfețe și combinat cu interfețele de multiplexare I/O existente, kernel-ul poate notifica o aplicație utilizator de orice tip de eveniment. Pentru a asigura în Linux posibilitatea așteptării de evenimente multiple s-a definit interfața ''​eventfd''​. Cu ajutorul acestei interfețe și combinat cu interfețele de multiplexare I/O existente, kernel-ul poate notifica o aplicație utilizator de orice tip de eveniment.
- 
-Interfața ''​eventfd''​ este prezentă în nucleul Linux începând cu versiunea 2.6.22 și este suportată de către glibc începând cu versiunea 2.8. 
  
 Interfața ''​eventfd''​ permite unificarea mecanismelor de notificare ale kernel-ului într-un descriptor de fișier care va fi folosit de utilizator. Interfața ''​eventfd''​ permite unificarea mecanismelor de notificare ale kernel-ului într-un descriptor de fișier care va fi folosit de utilizator.
Line 426: Line 451:
 ==== Linux AIO ==== ==== Linux AIO ====
  
-Standardul ''​POSIX.1b''​ definește ​un nou set de operații I/O care pot reduce semnificativ timpul pe care o aplicație îl petrece așteptând pentru I/O. Noile funcții permit unui program să inițieze una sau mai multe operații de I/O și să-și continue lucrul normal în timp ce operațiile de I/O sunt executate în paralel. ​+Începând cu versiunea 2.5.32, kernelul Linux expune ​un set de operații I/O care pot reduce semnificativ timpul pe care o aplicație îl petrece așteptând pentru I/O. Noile funcții permit unui program să inițieze una sau mai multe operații de I/O și să-și continue lucrul normal în timp ce operațiile de I/O sunt executate în paralel. ​
  
 Această funcționalitate este disponibilă dacă se instalează biblioteca ''​libaio'':​ <code bash> Această funcționalitate este disponibilă dacă se instalează biblioteca ''​libaio'':​ <code bash>
Line 436: Line 461:
 </​code>​ </​code>​
  
-Totodată, programul care folosește acest API trebuie să includă fișierul header ''​[[http://​www.koders.com/c/fid4725E35EA2BE17467E3BB724D74D9FA6A471BFE7.aspx | libaio.h]]''​ și să link-eze biblioteca ''​libaio''​. Toate funcțiile și structurile de care vom vorbi în continuare se pot găsi în acest fișier header. Dacă ați instalat pachetul, fișierul se găsește în ''/​usr/​include/​libaio.h''​.+Totodată, programul care folosește acest API trebuie să includă fișierul header ''​[[http://​libaio.sourcearchive.com/documentation/0.3.109-1ubuntu1/​libaio_8h_source.html ​| libaio.h]]''​ și să link-eze biblioteca ''​libaio''​. Toate funcțiile și structurile de care vom vorbi în continuare se pot găsi în acest fișier header. Dacă ați instalat pachetul, fișierul se găsește în ''/​usr/​include/​libaio.h''​.
  
 ====Structuri de bază Linux AIO==== ====Structuri de bază Linux AIO====
  
-Structura ''​iocb''​ folosită pentru încapsularea unei operații asincrone. Structura este definită în header-ul ''​[[http://​www.koders.com/c/fid4725E35EA2BE17467E3BB724D74D9FA6A471BFE7.aspx | libaio.h]]''​.+Structura ''​iocb''​ folosită pentru încapsularea unei operații asincrone. Structura este definită în header-ul ''​[[http://​libaio.sourcearchive.com/documentation/0.3.109-1ubuntu1/​libaio_8h_source.html ​| libaio.h]]''​.
 <code c> <code c>
 struct iocb { struct iocb {
Line 502: Line 527:
  
  
- ​Pentru folosirea acesteia o aplicație va include ''​[[http://​www.koders.com/c/fid4725E35EA2BE17467E3BB724D74D9FA6A471BFE7.aspx | libaio.h]]''​. Un exemplu de inițializare a acestei structuri este:+ ​Pentru folosirea acesteia o aplicație va include ''​[[http://​libaio.sourcearchive.com/documentation/0.3.109-1ubuntu1/​libaio_8h_source.html ​| libaio.h]]''​. Un exemplu de inițializare a acestei structuri este:
 <code c> <code c>
         #include <​libaio.h>​         #include <​libaio.h>​
Line 647: Line 672:
 int efd; int efd;
    
-/creare event cu valoare inițială 0, fără flaguri speciale+/creare event cu valoare inițială 0, fără flaguri speciale ​*/
 efd = eventfd(0, 0); efd = eventfd(0, 0);
    
Line 674: Line 699:
 Este un apel de sistem ce permite transferul de date între 2 descriptori de fișier, dintre care cel puțin unul este pipe. Avantajul este că nu se folosește un buffer (byte array) în userspace. ​ Este un apel de sistem ce permite transferul de date între 2 descriptori de fișier, dintre care cel puțin unul este pipe. Avantajul este că nu se folosește un buffer (byte array) în userspace. ​
 <code c> <code c>
-#define _GNU_SOURCE /trebuie definit pentru că splice este o extensie nespecificată de standardele POSIX/​SYSV/​BSD/​etc.+#define _GNU_SOURCE /trebuie definit pentru că splice este o extensie nespecificată de standardele POSIX/​SYSV/​BSD/​etc. ​*/
  
 #include <​fcntl.h>​ #include <​fcntl.h>​
Line 702: Line 727:
 size_t count = 4096; size_t count = 4096;
    
-/... deschideri fișiere, creare pipe+/... deschideri fișiere, creare pipe */
    
 splice(file1,​ &​offset,​ pipe, NULL, count, 0); splice(file1,​ &​offset,​ pipe, NULL, count, 0);
Line 772: Line 797:
 } }
 </​code>​ </​code>​
-===== Exercițiul 0 - Joc interactiv (2p) ===== 
  
-  * Detalii desfășurare [[http://​ocw.cs.pub.ro/​courses/​so/​meta/​notare#​joc_interactiv|joc]]. +===== Exerciții ​=====
- +
-===== Linux (9p) ===== +
- +
-În rezolvarea laboratorului folosiți arhiva de sarcini [[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab11-tasks.zip | lab11-tasks.zip]]+
  
 <note important>​ <note important>​
-Acest laborator se desfășoară în echipeO echipă este formată din 2 studenți. În cazul în care numărul de studenți prezenți este impar, o singură echipă va avea dreptul de a avea 3 studenți.+În cadrul laboratoarelor vom folosi repository-ul de git al materiei SO - https://​github.com/​systems-cs-pub-ro/​so. Va trebui sa clonați repository-ul pe masinile virtuale folosind comanda: ''​git clone https://​github.com/​systems-cs-pub-ro/​so''​. Dacă doriți să descărcați repositoryul în altă locație, folosiți comanda ''​git clone https://​github.com/​systems-cs-pub-ro/​so ${target}''​.
  
-Discutați exercițiile școlaborați pe parcursul întregului laboratorHave fun! :-)+Pentru a actualiza repository-ul,​ folosiți comanda ''​git pull origin master''​ din interiorul directorului în care se află repository-ul. Recomandarea este să îl actualizați cât mai frecvent, înainte să începeți lucrul, pentru a vă asigura că aveți versiunea cea mai recentăÎn cazul în care gitul detectează conflicte la nivelul vreunui fişier, folosiți următoarele comenzi pentru a vă păstra modificările: 
 +<​code>​ 
 +git stash 
 +git pull origin master 
 +git stash pop 
 +</​code>​ 
 + 
 +Pentru mai multe informații despre folosirea utilitarului git, urmați ghidul de la https://​gitimmersion.com.
 </​note>​ </​note>​
  
-==== Exercițiul 1 - poll (1p) ====+==== Linux ==== 
 + 
 +=== Exercițiul 1 - poll ===
  
 Intrați în directorul ''​1-pollpipe''​. Parcurgeți fișierul ''​poll.c''​ pentru a vedea un exemplu de folosire al funcției ''​poll''​. Intrați în directorul ''​1-pollpipe''​. Parcurgeți fișierul ''​poll.c''​ pentru a vedea un exemplu de folosire al funcției ''​poll''​.
Line 792: Line 821:
 Programul creează folosind ''​fork''​ o aplicație de test pentru ''​poll''​. Aplicația folosește un server (părintele) și ''​CLIENT_COUNT''​ clienți (copiii) ce comunică prin pipe-uri anonime. Programul creează folosind ''​fork''​ o aplicație de test pentru ''​poll''​. Aplicația folosește un server (părintele) și ''​CLIENT_COUNT''​ clienți (copiii) ce comunică prin pipe-uri anonime.
  
-Server-ul:+**Server-ul:**
   * construiește un vector de pipe-uri (în funcția ''​main''​);​   * construiește un vector de pipe-uri (în funcția ''​main''​);​
   * creează clienții;   * creează clienții;
   * se blochează în așteptarea datelor de la clienți și tipărește datele primite;   * se blochează în așteptarea datelor de la clienți și tipărește datele primite;
   * termină execuția după ce a primit date de la fiecare client; ​   * termină execuția după ce a primit date de la fiecare client; ​
-Clienții:+**Clienții:**
   * așteaptă un număr aleator de secunde (mai mic decât 10);   * așteaptă un număr aleator de secunde (mai mic decât 10);
-  * scriu în pipe-ul corespunzător un șir de ''​MSG_SIZE''​ caractere de forma ''​<​pid>:<​caracter random>'' ​('​a'​ + random() % 30);+  * scriu în pipe-ul corespunzător un șir de ''​MSG_SIZE''​ caractere de forma <​code>​<​pid>:<​caracter random> ('​a'​ + random() % 30)</​code>​
   * scrierile și citirile în pipe-uri de până la PIPE_BUF octeți (4096 pe Linux) sunt atomice. ​   * scrierile și citirile în pipe-uri de până la PIPE_BUF octeți (4096 pe Linux) sunt atomice. ​
  
Line 805: Line 834:
  
  
-==== Exercițiul 2 - epoll (2p) ===+=== Exercițiul 2 - epoll ===
-  - (**2 puncte**) ''​epoll''​ +
-       * Intrați în directorul ''​2-epollpipe''​. +
-       * Parcurgeți fișierul ''​epoll.c''​. +
-       * Considerând cerința de la exercițiul anterior, în loc de ''​poll''​ folosiți ''​epoll''​. +
-       * În partea de inițializare realizați următoare operații:​ +
-         * Inițializați,​ înainte de ciclul ''​for'',​ handle-ul de epoll folosing ''​epoll_create''​. +
-         * Adăugați câte un eveniment pentru fiecare pipe (folosind variabila ''​ev''​) folosind ''​epoll_ctl''​ cu opțiunea ''​EPOLL_CTL_ADD''​. +
-           * Câmpul ''​events''​ al variabilei ''​ev''​ îl veți inițializa la ''​EPOLLIN''​. +
-           * Câmpul ''​data.fd''​ al variabilei ''​ev''​ îl veți inițializa la capătul de citire al pipelului. +
-         * Închideți capătul de scriere al pipe-ului. +
-       * În partea de așteptare realizați, în bucla ''​while''​ următoarele operații:​ +
-         * Așteptați un eveniment folosind funcția ''​epoll_wait''​. +
-           * Descriptorul indicat în structura întoarsă de ''​epoll_wait''​ (adică ''​ev.data.fd''​) este capătul de citire al pipe-ului. +
-         * Din pipe citiți mesajul trimis de client, folosind ''​read''​. +
-         * Închideți pipe-ul (folosind ''​close''​) și eliminați-l din multiplexor (folosind ''​epoll_ctl''​ cu opțiunea ''​EPOLL_CTL_DEL''​). +
-         * Incremenetați valoarea variabilei ''​recv_msgs''​. +
-       * **Hints**:  +
-         * Urmăriți comentariile marcate cu // TODO // +
-         * Consultați secțiunea [[#​epoll|epoll]]+
  
 +Intrați în directorul ''​2-epollpipe''​ și parcurgeți fișierul ''​epoll.c''​. Considerând cerința de la exercițiul anterior, în loc de ''​poll''​ folosiți ''​epoll''​.
  
-==== Exercițiul 3 - eventfd (2p) ==== +În partea ​de inițializare realizați următoarele operații:​ 
-  - (**2 puncte**) ''​eventfd''​ +  Inițializați, înainte ​de ciclul ​''​for'', ​handle-ul ​de epoll folosing ​''​epoll_create''​. 
-        * Pornind ​de la codul scris pentru execițiul anterior, notificați serverul de terminarea unui client utilizând ''​eventfd''​. Clientul transmite mesaje către server și, când dorește să închidă comunicația,​ va trimite un mesaj pe canalul de control reprezentat de ''​eventfd''​. +  Adăugați câte un eveniment pentru fiecare pipe (folosind ​variabila ​''​ev''​) ​folosind ​''​epoll_ctl'' ​cu opțiunea ​''​EPOLL_CTL_ADD''​. 
-          * Acum, ''​epoll''​ este folosit pentru a demultiplexa atât descriptorii de pipe, cât și descriptorul de ''​eventfd''​. +     ​Câmpul ​''​events'' ​al variabilei ​''​ev'' ​îl veți inițializa la ''​EPOLLIN''​. 
-        * Decomentați în ''​epoll.c''​ linia cu <code c>#​define USE_EVENTFD</​code>​ +     ​Câmpul ​''​data.fd'' ​al variabilei ​''​ev'' ​îl veți inițializa la capătul ​de citire al pipelului
-        * Clientul va realiza ​următoarele operații:​ +  Închideți capătul ​de scriere al pipe-ului.
-          Va scrie mesaje în pipe-ul aferent. +
-          * La sfârșit va genera un mesaj de notificare. Va folosi funcția ''​set_event''​ definită în program. +
-            * Mesajul de notificare este un număr pe 64 de biți organizat astfel: +
-              * Primii 32 de biți conțin valoarea definită de macro-ul ​''​MAGIC_EXIT''​+
-              * Ultimii 32 de biți conțin indexul clientului. +
-        * Serverul va realiza următoarele operațiisuplimentar față ​de exercițiul anterior. +
-          * Adaugă descriptorul de ''​eventfd''​ în ''​epoll'' ​(cu eveniment de tipul ''​EPOLLIN''​)+
-          Așteaptă evenimente ​folosind ''​epoll_wait'' ​(așa cum făcea și până acum)+
-            * Apelul ​''​epoll_wait'' ​se întoarce când un descriptor din ''​epoll'' ​are informații de citit+
-            Descriptorul întors în urma ''​epoll_wait'' ​(identificat de câmpul ​''​ev.data.fd''​) poate fi descriptor de pipe sau poate fi descriptorul de ''​eventfd''​. +
-          Dacă descriptorul întors în urma ''​epoll_wait'' ​este descriptorul de ''​eventfd''​, atunci +
-            * Veți citi ''​64''​ de bițde pe acest descriptor (folosind ''​read''​)+
-            Dacă primii 32 biți sunt valoarea descrisă de macro-ul ''​MAGIC_EXIT'',​ atunci **scoate** ​capătul pipe-ului ​corespunzător din ''​epoll''​ și închide acel capăt. +
-              * Adică folosește ''​epoll_ctl''​ cu opțiunea ''​EPOLL_CTL_DEL''​ și apoi ''​close''​. +
-            * Pentru a extrage ultimii 32 de biți din mesajul de ''​64''​ de biți primit pe descriptorul de ''​eventfd'',​ reprezentând indexul clientului, folosiți funcția ''​get_index''​ definită local în program. +
-        * **Hints**:  +
-          * Consultați secțiunea [[#​eventfd|eventfd]]+
  
 +În partea de așteptare realizați, în bucla ''​while''​ următoarele operații:
 +  * Așteptați un eveniment folosind funcția ''​epoll_wait''​.
 +     * Descriptorul indicat în structura întoarsă de ''​epoll_wait''​ (adică ''​ev.data.fd''​) este capătul de citire al pipe-ului.
 +  * Din pipe citiți mesajul trimis de client, folosind ''​read''​.
 +  * Eliminați pipe-ul din multiplexor (folosind ''​epoll_ctl''​ cu opțiunea ''​EPOLL_CTL_DEL''​) și închideți-l folosind ''​close''​.
 +  * Incremenetați valoarea variabilei ''​recv_msgs''​.
  
-==== Exercițiul ​async I/O (KAIO) (2p) ==== +=== Exercițiul ​eventfd ​=== 
-  - (**3 puncte**) Asynchronous ​I/O (KAIO) + 
-         * Intrați în directorul ''​4-kaio''​+Pornind de la codul scris pentru execițiul anterior, notificați serverul de terminarea unui client utilizând ''​eventfd''​. Clientul transmite mesaje către server și, când dorește să închidă comunicația,​ va trimite un mesaj pe canalul de control reprezentat de ''​eventfd''​. Acum, ''​epoll''​ este folosit pentru a demultiplexa atât descriptorii de pipe, cât și descriptorul de ''​eventfd''​. 
-         * Parcurgeți fișierul ''​kaio.c''​. + 
-         ​* ​Completați zonele lipsă pentru a programa scrierea a 4 fișiere cu numele date de variabila ''​files''​. +Decomentați în ''​epoll.c''​ linia cu <code c>#​define USE_EVENTFD</​code>​ 
-         * Folosiți API-ul KAIO (io_setup, io_destroy, io_submit, io_getevents). +Clientul va scrie mesaje în pipe-ul aferent, iar la sfârșit va genera un mesaj de notificare. Acesta va folosi funcția ''​set_event''​ definită în program. Mesajul de notificare este un număr pe 64 de biți organizat astfel: 
-         ​* ​Folosiți **doar** io_getevents pentru așteptarea încheierii operațiilor asincrone. +  ​* Primii 32 de biți conțin valoarea definită de macro-ul ''​MAGIC_EXIT''​. 
-         * **Hints**: ​ +  * Ultimii 32 de biți conțin indexul clientului. 
-           * Parcurgeți secțiunea [[#​linux_aio|Linux AIO]]+ 
-           * Consultați exemplul lui [[http://​www.xmailserver.org/​eventfd-aio-test.c | Davide Libenzi]]. ​ +Serverul va adăuga descriptorul de ''​eventfd''​ în ''​epoll'' ​(cu eveniment de tipul ''​EPOLLIN''​). Evenimentele vor fi așteptate folosind ''​epoll_wait''​ (așa cum făcea și până acum). Apelul ''​epoll_wait''​ se întoarce când un descriptor din ''​epoll''​ are informații de citit. Descriptorul întors în urma ''​epoll_wait''​ (identificat de câmpul ''​ev.data.fd''​) poate fi descriptor de pipe sau poate fi descriptorul de ''​eventfd''​. 
-           ​* ​Urmăriți comentariile cu // TODO 1 // + 
-         * Compilați și rulați programul. Va trebui să aveți 4 fișiere de dimensiune ​8192 octeți create în ''/​tmp''​.  +Dacă descriptorul întors în urma ''​epoll_wait''​ este descriptorul de ''​eventfd'',​ atunci veți citi ''​64''​ de biți de pe acest descriptor (folosind ''​read''​). Dacă primii 32 biți sunt valoarea descrisă de macro-ul ''​MAGIC_EXIT'',​ atunci ​**scoate** capătul pipe-ului corespunzător din ''​epoll''​ și închide acel capăt (adică folosește ''​epoll_ctl''​ cu opțiunea ''​EPOLL_CTL_DEL''​ și apoi ''​close''​). Pentru a extrage ultimii 32 de biți din mesajul de ''​64''​ de biți primit pe descriptorul de ''​eventfd'',​ reprezentând indexul clientului, folosiți funcția ''​get_index''​ definită local în program. 
-           * **Atenţie!** În cazul în care, la compilare, header-ul '​libaio'​ nu este găsit rulaţi <code bash>+       
 +=== Exercițiul 4 - async I/O (KAIO) ​=== 
 + 
 +Intrați în directorul ''​4-kaio'' ​și parcurgeți fișierul ''​kaio.c''​. Completați zonele lipsă pentru a programa scrierea a 4 fișiere cu numele date de variabila ''​files''​. 
 + 
 +Folosiți API-ul KAIO (io_setup, io_destroy, io_submit, io_getevents). Folosiți **doar** io_getevents pentru așteptarea încheierii operațiilor asincrone. 
 + 
 +Parcurgeți secțiunea [[#​linux_aio|Linux AIO]] și consultați exemplul lui [[http://​www.xmailserver.org/​eventfd-aio-test.c | Davide Libenzi]]. Urmăriți comentariile cu // TODO 1 // 
 + 
 +Compilați și rulați programul. Va trebui să aveți 4 fișiere de dimensiune ​''​BUFSIZ'' ​octeți create în ''/​tmp''​.  
 + 
 +**Atenţie!** În cazul în care, la compilare, header-ul '​libaio'​ nu este găsit rulaţi <code bash>
 so$ sudo apt-get install libaio1 libaio-dev so$ sudo apt-get install libaio1 libaio-dev
 </​code>​ </​code>​
  
  
-==== Exercițiul 5 - async I/O (KAIO) (2p==== +=== Exercițiul 5 - async I/O (KAIO) === 
-  - (**2 puncte**) Asynchronous I/O (KAIO) + eventfd + 
-         * Folosiți ''​eventfd''​ pentru așteptarea operațiilor asincrone. + ​Folosiți ''​eventfd''​ pentru așteptarea operațiilor asincrone. Porniți de la codul scris pentru execițiul anterior. 
-           ​* ​Porniți de la codul scris pentru execițiul anterior. + 
-           * Decomentați în ''​kaio.c''​ linia cu <code c>#​define USE_EVENTFD</​code>​ +Decomentați în ''​kaio.c''​ linia cu <code c>#​define USE_EVENTFD</​code>​ 
-           * La inițializarea structurilor ''​iocb'',​ folosiți funcția ''​io_set_eventfd''​ pentru a activa folosirea ''​eventfd''​ +La inițializarea structurilor ''​iocb'',​ folosiți funcția ''​io_set_eventfd''​ pentru a activa folosirea ''​eventfd''​Completați funcția ''​wait_aio''​ pentru a aștepta terminarea operațiilor asincrone folosind ''​eventfd''​. 
-           ​* ​Completați funcția ''​wait_aio''​ pentru a aștepta terminarea operațiilor asincrone folosind ''​eventfd''​ + 
-         * **Hints**: ​ +Parcurgeți secțiunea [[#​linux_aio|Linux AIO]] și urmăriți comentariile cu // TODO 2 //Consultați exemplul lui [[http://​www.xmailserver.org/​eventfd-aio-test.c | Davide Libenzi]].  
-           * Parcurgeți secțiunea [[#​linux_aio|Linux AIO]]+ 
-           * Urmăriți comentariile cu // TODO 2 // +Compilați și rulați programul. Va trebui să aveți 4 fișiere de dimensiune 8192 octeți create în ''/​tmp''​. 
-           ​* ​Consultați exemplul lui [[http://​www.xmailserver.org/​eventfd-aio-test.c | Davide Libenzi]].  + 
-         * Compilați și rulați programul. Va trebui să aveți 4 fișiere de dimensiune 8192 octeți create în ''/​tmp''​.  +==== BONUS ====
-===== BONUS =====+
  
-  - **(1 so karma)** ​''​signalfd''​+  - ''​signalfd''​
      * Modificați codul de la exercițiul 2 pentru a permite notificarea de terminare a clienților bazată pe semnale.      * Modificați codul de la exercițiul 2 pentru a permite notificarea de terminare a clienților bazată pe semnale.
      * Server-ul:      * Server-ul:
Line 891: Line 901:
        * Consultați secțiunea [[#​signalfd|signalfd]]        * Consultați secțiunea [[#​signalfd|signalfd]]
        * [[ http://​linux.die.net/​man/​2/​signalfd | man signalfd ]]        * [[ http://​linux.die.net/​man/​2/​signalfd | man signalfd ]]
-===== Soluții ===== 
  
-[[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab11-sol.zip | Soluţii laborator 11]]  
so/laboratoare/laborator-11.1431899926.txt.gz · Last modified: 2015/05/18 00:58 by laura.vasilescu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0