select和epoll的区别详解

1. 名词解释

1.1 文件描述符fd

文件描述符(File descriptor)是计算机科学中的一个术语,是一个用于表述指向文件的引用的抽象化概念。

文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。

1.2 阻塞和非阻塞的区别

阻塞I/O会一直阻塞住对应的进程直到操作完成;

非阻塞I/O在内核准备数据的情况下会立刻返回;

1.3 I/O多路复用

通过一种机制一个进程能同时等待多个文件描述符(fd),而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态,select()函数就可以返回。

2. select

2.1 原型

select(fd_set read[],fd_set [],fd_set [],timeout)

select仅仅知道了有I/O事件发生,却并不知道是哪几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作。所以select具有O(n)的无差别轮询复杂度,同时处理的流越多,无差别轮询时间就越长。

2.2 本质

select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理。这样所带来的缺点是:

1)单个进程可监视的fd数量被限制,即能监听端口的大小有限。

一般来说这个数目和系统内存关系很大,具体数目可以cat /proc/sys/fs/file-max察看。32位机默认是1024个。64位机默认是2048.

2)对socket进行扫描时是线性扫描,即采用轮询的方法,效率较低:

 当套接字比较多的时候,每次select()都要通过遍历FD_SETSIZE个Socket来完成调度,不管哪个Socket是活跃的,都遍历一遍。这会浪费很多CPU时间。如果能给套接字注册某个回调函数,当他们活跃时,自动完成相关操作,那就避免了轮询,这正是epoll与kqueue做的。

3)需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大

2.3 调用过程

1)从用户空间拷贝fd_set到内核空间,也即从当前程序拷贝fd_set数组进内核;

2)对所有的fd进行一次poll操作,即把当前进程挂载到fd上。

3)poll操作过程中select会唤醒所有的队列中节点,进行遍历,得到它们的掩码(不同的掩码表示不同的就绪状态)。

4)如果所有设备返回的掩码都没有显示任何的事件触发,就去掉回调函数的函数指针,进入有限时的睡眠状态,再恢复和不断做poll,再作有限时的睡眠,直到其中一个设备有事件触发为止。

5)只要有事件触发,系统调用返回,将fd_set从内核空间拷贝到用户空间,回到用户态,用户就可以对相关的fd作进一步的读或者写操作了。

2.4 时间复杂度

O(n)

2.5 select的缺点

1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大

2)同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大

3)select支持的文件描述符数量太小了,默认是1024

3. poll

3.1 原型

int poll (struct pollfd *fds, unsigned int nfds, int timeout);

poll将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态。它是基于链表存储的,故没有最大连接数的限制。

3.2 实现

poll使用一个 pollfd的指针实现。

struct pollfd {
    int fd; /* file descriptor */
    short events; /* requested events to watch */
    short revents; /* returned events witnessed */
};

pollfd结构包含了要监视的event和发生的event,不再使用select“参数-值”传递的方式。 和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符。

3.3 时间复杂度

O(n)

3.4 poll与select的异同

1)不同点:pollfd并没有最大数量限制(数据量过大后也会造成性能下降),select支持的文件描述符最大为1024;

2)相同点:和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符;

未完待续。。。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值