[問題] 想請問一個epoll以及pipe的問題

作者: anti5566 (^^)   2015-07-28 19:11:43
開發平台(Platform): (Ex: VC++, GCC, Linux, ...)
c++11
問題(Question):
當pipe在其他thread瞬間大量寫入時,
epoll_wait只會被喚醒一次,
如果沒一次把data全部讀完就會卡在epoll_wait
除非改成epoll_wait(efd, events, MAXEVENTS, 1000);
預期的正確結果(Expected Output):
每輪只從各fd讀取一部份資料,
要如何得知還有data未讀取,
並在下一輪繼續讀取剩下的資料呢?
程式碼(Code):(請善用置底文網頁, 記得排版)
以下是簡化後示意的程式碼:
http://codepad.org/8af9AZkm
g++ -o main.o main.cpp
作者: Feis (永遠睡不著 @@)   2015-07-28 22:06:00
不確定需求. 你不能就一直讀讀到完?
作者: LiloHuang (十年一刻)   2015-07-28 23:03:00
你需要有一個結構來紀錄每個 fd 上次讀了多少 byte等到該 fd 下次又可以讀取時,寫入時的 buffer 加上之前已經紀錄的 byte 數,當作是 offset 來寫入大多數的 non-blocking I/O multiplexing 都是這樣寫的目的就是每個 fd 都要被讀取一點,簡單點可以開一個array (e.g. size_t avaiLen[MAX_FDS]) 之類的作法把每次 read (or recv) 回傳的長度,針對fd作一個紀錄non-blocking I/O multiplexing 的重點就是要輪流讀取千萬不要寫 loop 硬是把資料給讀完,這樣就失去意義了另外,你得考慮你的通訊協定,或者實作一個自動狀態機進而得知當前讀取的 buf 已經可以進行 parse 之類的修正用語,是 FSM 有限狀態自動機。還有這篇文章可以看看,reactor pattern 就是你想要的http://goo.gl/ULuXrX Reactor (Douglas C. Schmidt)另外,每個 fd 都要有自己的 buffer,這樣才能夠多工建議可以直接用一個結構來儲存 buf 跟 avaiLen 之類的e.g. struct ctx { char buf[8192]; size_t len; };
作者: anti5566 (^^)   2015-07-29 13:37:00
非常謝謝您們的回答^^嗯嗯我預計會有個connect物件來記錄這些用select就能達到我想要的~不過epoll就會卡住QQhttp://codepad.org/LdltMzU4 這是改用select的程式碼
作者: LiloHuang (十年一刻)   2015-07-29 17:45:00
再看一次你的程式,你得把EPOLLET改EPOLLLT,才會持續通知。不然就得寫迴圈把資料讀玩。這樣就有別一般的select()用法了。改看看再回報結果吧:)
作者: anti5566 (^^)   2015-07-29 21:30:00
哇可以了耶~非常謝謝您ubutun 14.10 EPOLLLT已經是epoll預設模式拿掉EPOLLLT即可^^
作者: LiloHuang (十年一刻)   2015-07-29 21:34:00
恭喜你,建議這篇文章也可以看看 http://goo.gl/3oBXMm進而理解 EPOLLET 與 EPOLLLT (預設) 的差異

Links booklink

Contact Us: admin [ a t ] ucptt.com