[问题] 想请问一个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