看板 C_and_CPP 關於我們 聯絡資訊
開發平台(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 --std=c++0x -lpthread 請問一般時如何實作這種不會一次讀完的情況呢? 或是當要read的資料(stream)超過buffer時, 要如何每次只讀取各stream的一部分呢? 麻煩各為可以替我解答, 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 220.129.49.238 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1438081908.A.1B3.html
Feis: 不確定需求. 你不能就一直讀讀到完? 07/28 22:06
LiloHuang: 你需要有一個結構來紀錄每個 fd 上次讀了多少 byte 07/28 23:03
LiloHuang: 等到該 fd 下次又可以讀取時,寫入時的 buffer 加上 07/28 23:03
LiloHuang: 之前已經紀錄的 byte 數,當作是 offset 來寫入 07/28 23:03
LiloHuang: 大多數的 non-blocking I/O multiplexing 都是這樣寫的 07/28 23:05
LiloHuang: 目的就是每個 fd 都要被讀取一點,簡單點可以開一個 07/28 23:06
LiloHuang: array (e.g. size_t avaiLen[MAX_FDS]) 之類的作法 07/28 23:08
LiloHuang: 把每次 read (or recv) 回傳的長度,針對fd作一個紀錄 07/28 23:09
LiloHuang: non-blocking I/O multiplexing 的重點就是要輪流讀取 07/28 23:10
LiloHuang: 千萬不要寫 loop 硬是把資料給讀完,這樣就失去意義了 07/28 23:11
LiloHuang: 另外,你得考慮你的通訊協定,或者實作一個自動狀態機 07/28 23:13
LiloHuang: 進而得知當前讀取的 buf 已經可以進行 parse 之類的 07/28 23:14
LiloHuang: 修正用語,是 FSM 有限狀態自動機。 07/28 23:15
LiloHuang: 還有這篇文章可以看看,reactor pattern 就是你想要的 07/28 23:16
LiloHuang: http://goo.gl/ULuXrX Reactor (Douglas C. Schmidt) 07/28 23:16
LiloHuang: 另外,每個 fd 都要有自己的 buffer,這樣才能夠多工 07/28 23:19
LiloHuang: 建議可以直接用一個結構來儲存 buf 跟 avaiLen 之類的 07/28 23:22
LiloHuang: e.g. struct ctx { char buf[8192]; size_t len; }; 07/28 23:23
anti5566: 非常謝謝您們的回答^^ 07/29 13:37
anti5566: 嗯嗯我預計會有個connect物件來記錄這些 07/29 13:37
anti5566: 用select就能達到我想要的~不過epoll就會卡住QQ 07/29 13:44
anti5566: http://codepad.org/LdltMzU4 這是改用select的程式碼 07/29 13:48
LiloHuang: 再看一次你的程式,你得把EPOLLET改EPOLLLT,才會持續 07/29 17:45
LiloHuang: 通知。不然就得寫迴圈把資料讀玩。這樣就有別一般的 07/29 17:46
LiloHuang: select()用法了。改看看再回報結果吧:) 07/29 17:48
anti5566: 哇可以了耶~非常謝謝您 07/29 21:30
anti5566: ubutun 14.10 EPOLLLT已經是epoll預設模式 07/29 21:31
anti5566: 拿掉EPOLLLT即可^^ 07/29 21:32
LiloHuang: 恭喜你,建議這篇文章也可以看看 http://goo.gl/3oBXMm 07/29 21:34
LiloHuang: 進而理解 EPOLLET 與 EPOLLLT (預設) 的差異 07/29 21:34