<div dir="ltr">Multumesc Adrian, pentru explicatii.</div><div class="gmail_extra"><br><div class="gmail_quote">Pe 22 mai 2017, 17:31, Adrian Stanciu <span dir="ltr"><<a href="mailto:adrian.stanciu.pub@gmail.com" target="_blank">adrian.stanciu.pub@gmail.com</a>></span> a scris:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">2017-05-22 16:04 GMT+03:00 Theodor Stoican <<a href="mailto:theo.stoican@gmail.com">theo.stoican@gmail.com</a>>:<br>
> Ok, am inteles. Si, practic, ce ziceai tu (mai jos), trebuie implementat la<br>
> nivelul fiecarei conexiuni:<br>
><br>
>> Poți să:<br>
>> * activezi EPOLLIN pe eventfd pentru a aștepta finalizarea citirii<br>
>> asincrone a unei bucăți din fișier<br>
>> * planifici citirea asincronă a unei bucăți din fișier<br>
>> * activezi EPOLLOUT pe socket<br>
>> * când ești notificată de epoll că poți să trimiți pe socket, trimiți<br>
>> bucata de fișier<br>
>> * dacă nu s-a trimis întreaga bucată mai aștepți un nou eveniment de<br>
>> EPOLLOUT pe socket din partea epoll și apoi trimiți ce ți-a mai rămas<br>
>> și tot așa<br>
>> * când ai terminat de trimis acea bucată, dezactivezi EPOLLOUT pe<br>
>> socket (căci deocamdată nu mai ai ce trimite)<br>
>> * o iei de la capât pentru a citi următoarea bucată din fișier<br>
><br>
>> * când ai trimis întreg fișierul se poate închide conexiunea<br>
><br>
> Dar daca faci asta, nu inseamna ca ramai blocat pe o anumita conexiune?<br>
> Practic, celelalte conexiuni vor stagna in felul asta pana se trimite tot<br>
> fisierul.<br>
<br>
</span>Nu se va bloca pe o anumită conexiune, toată treaba se face prin epoll.<br>
<br>
În obiectul epoll vei avea:<br>
* socket-ul serverului pentru listen (pentru a accepta conexiuni noi)<br>
* eventfd-uri pentru fiecare conexiune (pentru notificare terminare<br>
citire asincronă)<br>
* sockeții non-blocanți pentru fiecare conexiune (pentru trimitere fișiere)<br>
<br>
Când epoll_wait() te notifică pe un eventfd sau pe un socket, tu vei<br>
lua o acțiune ce nu este blocantă:<br>
* ori vei planifica o citire asincronă a unui chunk din fișier<br>
* ori vei fi notificat că citirea s-a terminat<br>
* ori vei trimite pe un socket non-blocant chunk-ul respectiv<br>
<br>
Astfel, se pot intercala operații pe mai multe conexiuni și niciuna nu<br>
va aștepta după alta.<br>
<div class="HOEnZb"><div class="h5"><br>
> Pe 22 mai 2017, 14:57, Adrian Stanciu <<a href="mailto:adrian.stanciu.pub@gmail.com">adrian.stanciu.pub@gmail.com</a>> a<br>
> scris:<br>
>><br>
>> 2017-05-22 14:36 GMT+03:00 Theodor Stoican <<a href="mailto:theo.stoican@gmail.com">theo.stoican@gmail.com</a>>:<br>
>> > Salut,<br>
>> ><br>
>> > Merci pentru explicatii. Totusi, mai este ceva ce nu inteleg:<br>
>> ><br>
>> > In cazul in care citirile asincrone sunt integrate cu eventfd, pentru a<br>
>> > primi notificare de la kernel ca o citire s-a incheiat (in main, cand<br>
>> > apelam<br>
>> > epoll), de ce mai avem nevoie de un eventfd per conexiune (cum este<br>
>> > precizat<br>
>> > in enunt)?<br>
>> ><br>
>><br>
>> Fiecare conexiune va avea operațiile sale de citire independent de<br>
>> celelalte conexiuni. Din această cauză vei avea un eventfd per<br>
>> conexiune, care te va notifica atunci când o operație de citire<br>
>> asincronă s-a încheiat pentru conexiunea respectivă. Asta este trecută<br>
>> în enunț ca recomandare.<br>
>><br>
>> Dacă ai avea un singur eventfd (global, pentru toate conexiunile)<br>
>> atunci ar fi mai dificil de implementat pentru că:<br>
>> * ar trebui să ai un mecanism suplimentar de găsire a conexiunii<br>
>> pentru care a fost generat evenimentul<br>
>> * ar trebui să tratezi evenimentele agregate (o singură citire de pe<br>
>> eventfd să-ți raporteze mai multe evenimente generate).<br>
>><br>
>> > Pe 22 mai 2017, 12:53, Adrian Stanciu <<a href="mailto:adrian.stanciu.pub@gmail.com">adrian.stanciu.pub@gmail.com</a>> a<br>
>> > scris:<br>
>> >><br>
>> >> 2017-05-22 12:32 GMT+03:00 Theodor Stoican via so<br>
>> >> <<a href="mailto:so@cursuri.cs.pub.ro">so@cursuri.cs.pub.ro</a>>:<br>
>> >> > Scuze, am trimis inainte de a finisa mail-ul, din greseala.<br>
>> >> ><br>
>> >> > Revin:<br>
>> >> > Cum ar trebui sa abordam citirea dintr-un fisier asincron, respectiv<br>
>> >> > scrierea pe socket (tot asincron)? Mai specific, cand ar trebui sa<br>
>> >> > apelam<br>
>> >> > io_getevents astfel incat sa nu devina totul blocant?<br>
>> >> ><br>
>> >> > Spre exemplu, in acest sample[1], se asteapta cu io_get_events pana<br>
>> >> > se<br>
>> >> > termina toate operatiile de write, respectiv de read, daca am inteles<br>
>> >> > eu<br>
>> >> > bine. De asemenea, nu inteleg cum ar trebui sa abordam problema asta,<br>
>> >> > avand<br>
>> >> > un eventfd pentru fiecare conexiune. Nu ar trebui sa legam totul cu<br>
>> >> > io_submit la un eventfd global, folosit si de epoll?<br>
>> >> ><br>
>> >> > [1] <a href="http://www.xmailserver.org/eventfd-aio-test.c" rel="noreferrer" target="_blank">http://www.xmailserver.org/<wbr>eventfd-aio-test.c</a><br>
>> >> ><br>
>> >><br>
>> >> Salut, Theodor,<br>
>> >><br>
>> >> Ai urmărit discuția asta [1]? Sunt oferite acolo niște hint-uri.<br>
>> >><br>
>> >> [1] <a href="http://cursuri.cs.pub.ro/pipermail/so/2015-May/016884.html" rel="noreferrer" target="_blank">http://cursuri.cs.pub.ro/<wbr>pipermail/so/2015-May/016884.<wbr>html</a><br>
>> >><br>
>><br>
>><br>
<br>
Adrian<br>
</div></div></blockquote></div><br></div>