Articles of epoll

一个单线程的NGINX如何处理这么多的连接?

NGNIX使用epoll通知来了解套接字上是否有数据要读取。 假设:有两个请求到服务器。 nginx注意到这两个请求,并开始: 接收第一个请求 parsingist头 检查badary(体型) 发送第一个请求到上游服务器 等等 nginx是单线程的,只能同时执行一个操作。 但是第二个请求会发生什么? 在parsing第一个请求时,nginx是否收到第二个请求? 或者在第一次完成后开始处理第二个请求? 或者其他我不明白的东西。 如果1.是正确的,我不明白如何在一个单一的线程内是可能的。 如果2.是正确的,nginx怎么会这么快? 因为nginx按顺序处理所有传入的请求。 在任何时候,只有一个请求处理是可能的。 请帮我理解。 谢谢

一个nginx工作进程是否同时或一个地处理两个请求?

关于filter链的非常酷的部分是每个filter不等待前一个filter完成; 它可以处理前一个filter的输出,就像Unixpipe道一样。 (从这里 ) 我想上面是在每个filter的末尾谈论这样的代码: if (!chain_contains_last_buffer) return ngx_http_next_body_filter(r, in); 也就是说,nginx逐个链接filter。 但是,因为它在每个filter的末尾 ,所以必须等到当前filter完成。 我看不出nginx如何设法让each filter doesn't wait for the previous filter to finish 。 所以上面是关于nginxfilter的并发性,接下来是关于nginx请求处理的并发性: 正如我们所知,nginx使用epoll来处理请求: events = epoll_wait(ep, event_list, (int) nevents, timer); for (i = 0; i < events; i++) { … rev->handler(rev); } 用上面的代码,我不认为nginx可以同时处理两个请求,它只能一个接一个地完成(每个handler完成它的工作足够快,所以下一个请求得到很快处理),对吧? 还是有什么遗失我错过了?

为什么TUX Web服务器死机? Nginx / Lighttpd / Epoll / Kqueue取代它吗?

我记得一个非常快的Linux内核模块,称为“TUX”,用于静态文件,以回答IIS优于Linux的静态文件Web服务性能并解决“C10K问题”。 现在我继续看到: Nginx的 Lighttpd的 的CDN …为“快速静态文件服务”。 如果您的操作系统具有正确的function,快速提供静态文件并不困难。 自从IO完成端口,重叠I / O等发明以来 Tux是否因为安全隐患而死亡? Kqueue / Epoll与Sendfile之类的function结合在一起是否过时了? 什么是最好的解决scheme来服务100%的静态内容 – 比如50个左右的图像模拟一个“animation书”电影packshots。 我明白这个“服务器相关”的问题,但这也是理论上的。 如果它纯粹是静态的,CDN真的会更好吗?

“epoll”是Tornadoweb(或Nginx)如此之快的重要原因吗?

Tornadoweb和Nginx是目前stream行的Web服务器,许多基准testing表明它们在某些情况下比Apache有更好的性能。 所以我的问题是: “epoll”是使他们如此之快的最重要的原因吗? 如果我想写一个好的套接字服务器,我可以从中学到什么?

我们可以使用epoll()来轮询正在使用ioctl进行数据传输的描述符

我来到一个情况下,我必须轮询文件描述符使用ioctl命令进行数据传输(不使用read())的事件。 我知道epoll()可以用在使用read()和write()进行数据传输的文件描述符上。 但有些驱动程序使用ioctl命令进行数据传输。 我们可以在这些types的文件描述符上使用epoll()吗?

主stream内核中的EPOLLEXCLUSIVE和EPOLLROUNDROBIN标志

我发现这个链接关于另外两个EPOLL标志。 有谁知道他们什么时候可以在主stream的linux内核中使用?

epoll:当EPOLLONESHOT指定时,电平触发和边沿触发之间的差异

当EPOLLONESHOT指定时,电平触发和边缘触发模式有什么区别? 这里也有类似的问题。 “蹲小猫”的答案似乎并不正确(据我所知,其他答案不能回答我的问题)。 我已经尝试了以下内容: 服务器向客户端发送2个字节,而客户端在epoll_wait等待 客户端从epoll_wait返回,然后读取1个字节。 客户重新武装事件(由于EPOLLONESHOT) 客户端再次调用epoll_wait 。 在这里,对于两种情况(LT和ET), epoll_wait不会等待,而是立即返回(与“蹲小猫”的回答相反) 客户端可以读取第二个字节 当EPOLLONESHOT指定时,LT和ET之间是否有区别?

使用less量文件描述符的epoll有什么好处吗?

下面的单线程UDP客户端应用程序是否看到使用epoll而不是简单地在非阻塞套接字上调用recvfrom / sendto会带来性能好处? 让我解释客户。 我正在写单线程的UDP客户端(自定义协议),使用非阻塞I / O发送和接收数据,我的同事build议我使用epoll为此。 客户端发送和接收多个信息包,这些信息包都与唯一的会话ID相关联,并且可以同时运行多个会话。 如果我使用epoll,epoll_wait可能会等待10-20个文件描述符的数量。 每个文件描述符将与一个会话相关联。 所以这是最多10 – 20个会议,这个数字将被强制执行。 每个会话都有自己的状态机。 从一个线程我需要经常合理地运行每个状态机,并轮询关联的套接字。 在我的情况下,我不得不使用epoll_wait超时为零或一些非常小的值,以便我可以给CPU时间来运行每个会话的状态机。 如果会话有数据,则需要将其导向到关联的状态机。 但是,使用如此less量的文件描述符,我看不出有什么好处。 我看到的方式是我有两个devise选项:1.在我使用epoll的主循环中,我可以使用epoll_wait轮询描述符,可以使用一个小超时或不超时。 在这一点上它是如何处理数据的地方是我有点卡住了…要么我马上读它,然后把它放到一个队列中,让每个状态机运行时,或者我在状态机来告诉它数据正在等待状态机运行时,它会通过调用recvfrom来获取数据。 或者,我读取数据并立即处理,并为其运行状态机。 或者… 2,从主循环中运行每个状态机并调用recvfrom。 如果我得到一些数据,处理它。 如果我不这样做,那么做任何其他状态机需要。 当没有数据时,是否有巨大的开销调用recvfrom? 随着去的epoll路线我编码在一些额外的复杂性。 如果在我的情况下有更强的可能性,那么我会开始做。 但是,如果第二种方法真的很简单,那么我不会使用epoll。 有什么想法吗?

epoll集合中fd和关联状态的映射

当您将一个fd添加到epoll集时,可以使用“struct epoll_event.data”将某个状态与它关联。 当epoll在fd上报告一个事件时,它当然会把相关数据和事件一起返回给用户。 这意味着epoll集合正在维护fds和相关状态之间的映射。 假设我将epoll_event.data.ptr设置为dynamic分配的某些状态,并且在将来的某个时刻,我想从epoll集合中删除fd,从而释放之前在ptr中设置的内存。 据我所知,对于我来说,没有一个程序化的方法来查找一个epd集合中与fd相关的状态来完成上述任务。 我目前维护我自己的FDS和相关联的状态之间的映射。 我明白,保持这种映射不需要太多的内存,但我仍然觉得在两个不同的地方维护相同的映射效率不是很高。 所以我的问题是:有没有办法检索一个epd集合中的fd相关的状态?

替代epoll_wait,它不等待文件描述符?

我有一个程序使用timerfd_create(计时器到期时,设置文件描述符)创build一个计时器。 问题是,我正在使用epoll_wait等待文件描述符,然后使用fd=revent.data.fd和fd=timer_fd (请参阅下面的程序)检查到期fd=revent.data.fd 。 但是,如果我这样做, epoll_wait阻止我的程序,直到计时器到期,我不希望这种情况发生..我希望程序运行,并定期我会检查计时器到期。 有没有其他办法呢? 请参阅下面的程序。 enter code here #include <sys/timerfd.h> #include <sys/time.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/epoll.h> #include <time.h> int main() { struct itimerspec its; struct epoll_event event, revent; int timer_fd, efd, fd1, fd2; /* Setting timer interval */ its.it_interval.tv_sec=1; its.it_interval.tv_nsec=0; /* Setting timer expiration */ its.it_value.tv_sec=5; its.it_value.tv_nsec=0; efd=epoll_create(2); […]