poll、select和epoll

2018/07/23

在一个web server程序中,我们需要读取client请求的输入,并且需要将服务端的数据返回给client。在linux(Unix)系统中,任何资源都是文件,即fd(文件描述符),所以我们需要监控需要的fd,以便可读时,读取client的输入,可写时,向client返回服务端的数据。

假设程序有100个client访问,那么就需要从100个fd中读取数据,那么怎么做呢?

可以为每一个client生成一个thred或者process(线程或者进程)来处理请求,但是很显然当client越来越大的时候,就会非常消耗资源,因为(???)

select & poll

这两种方法是任何Unix系统都有的,epoll只有linux有,他们的工作方式都是:

select和poll的定义

poll返回了很多可能的fd处理结果,而select只返回了输入/输出/错误(select内部做了转换)

另外一个区别就是:如果只想知道1,3,4,19四个fd的信息,poll会遍历所有的19个fd,而select只会遍历这4个

虽然select好一点,但是他们实际上还是依靠循环实现的,所以时间负复杂度是O(N)

信号驱动IO

当fd发生变化的时候,让内核给你发一个信号

什么时候会内核会发出信号呢,有两种模式

epoll

    #include <sys/epoll.h>
    int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

他的参数:

    #include <sys/epoll.h>
    int epoll_wait(int epfd, struct epoll_event *evlist, int maxevents, int timeout);

他的参数:

timeout参数的含义:

epoll_wait的返回值

poll select 和 epoll的性能对比

# operations  |  poll  |  select   | epoll
10            |   0.61 |    0.73   | 0.41
100           |   2.9  |    3.0    | 0.42
1000          |  35    |   35      | 0.53
10000         | 990    |  930      | 0.66

参考