问题应该在接收端。用epoll要注意ET和LT。
有这种可能就是:你用的epoll是工作有ET模式下,而你又的传进去的buffer不够大的时候,一次读不完,即状态不改变,然后下次用epoll_wait时就一直等不到通知了。
估计问题就是这个了,,
改为m_ev.events = EPOLLIN; //去掉EPOLLET就行了
我想问题应该解决了,,,
如果你非要使用ET触发的话,,那么读数据时,就一直读取,处理,再读取再处理,直到recv返回-1且errno =EAGAIN.然后才返回主循环epoll_wait。
数据不要轻易走pipe, 用pipe来做事件通知, 将待处理的数据包放在内存队列里, I/O线程也不用同步的等, 将待处理包丢给处理线程, 自己注册个write事件就可以继续干别的事了, 等处理线程处理完了把结果丢到队列里, 往I/O线程的pipe丢1字节就行了, I/O线程可以将结果对应的client的状态改为已完成, 等client的write事件再次触发就可以检测到已完成, 就可以继续往下干事了, 整个过程一定是可异步的.
实际优秀的设计是需要状态机这种简单的机制来帮助程序员解脱的, 而且绝大多数服务端也就是这么实现的, 一个client将会经历一系列的状态, 在一个状态逗留等待异步处理是完全可行的, 并且是不需要阻塞其他client的, 只要你保证给这个client一个等待超时检测或者你保证异步处理一定会有结果事件触发client.
lighttpd/nginx的设计就是一个典型的一应一答的协议, 但这不意味着就要阻塞等, 在接受到http请求后, 接下来注册write事件开始应答, 在write事件触发图书管理系统论文 后遍历所有callback module, 比如第一个module是vhost Module, 它会根据请求的port/host选择一个正确的文档根目录, 这个操作会立即成功, 于是继续下一个module的回调, 结果这一步是PHP CGI吧, 于是fork+pipe+dup2, 一套完事了, 注册监听pipe, 然后这个回调没有立即结束, 于是这次write事件结束. 之后就php cgi module在event loop里从pipe读数据放到client的output buffer里. 当然, client的write事件继续触发, 一方面将output buffer实际写出, 另一方面会继续回调php cgi module询问该module是否结束以便继续回调下一个module, 这就是client处于一个应答状态, 并且卡在php cgi上, 直到某一个pipe读完了, pipe的event callback会设置对应client的php cgi module的module data中的状态位为完成, 下一次client write事件触发回调php cgi module callback时, php cgi module就放行了. 就是这么一个过程. 不需要阻塞什么.