select/poll/epoll 区别 学习笔记

来源:互联网 发布:spss手机版软件 编辑:程序博客网 时间:2024/05/22 02:59

select和epoll效率差的原因:select是轮询的,而epoll是触发式的,所以epoll的效率高;

select:

原型:

int select(

int nfds, // 本参数忽略,只为与Berkeley套接字兼容

fd_set* readfds,// 可选,指向一组等待可读性检查的套接字的指针  

fd_set* writefds,// 可选,指向一组等待可写性检查的套接字的指针

fd_set* exceptfds,// 可选,指向一组等待错误检查的套接字的指针

const struct timeval* timeout// select等待的最长时间,如果想阻塞则设置为NULL

);

- socket数量(文件描述符更准确一些)限制:该模式可操作的socket数量有FD_SETSIZE(宏),内核默认32*32=1024.Windows默认是64,可通过WinSock2.h修改;

- 操作限制:通过遍历FD_SETSIZE个socket来完成调度,不管哪一个socket是活跃的,都要全部遍历一遍:(如果socket数量小并且均很活跃,那么select效率还是不错的)

- 其他:每次调用都要将fd从用户态拷贝到内核态;

- 说明:无论遍历还是拷贝,这种效率都是线性下降的;

- select小结:

select效率底下是select机制本身决定的,与操作系统无关,任何内核在实现select时都必须做遍历——轮询,才能知道哪些socket是准备好的,这会消耗cpu;

当有一个很大的socket集合时,尽管我们只关心那些活跃的socket,即准备好的、我们可以直接拿过来读或者写操作,但是我们不得不每次都将所有的socket填入到FD_SET中,这也会消耗CPU;

poll:

- socket数量几乎没有限制:该模式下的socket对应的fd列表由一个数组保存,大小不限(默认4K),这个值跟系统的内存关系很大;

- 操作限制:同select

- 其他:同样每次调用都需要将包含所有fd的数组从用户态拷贝到内核态;

- 说明:同select

epoll:

- socket数量无限制:同poll;

- 操作无限制:基于内核提供的反射模式(回调机制),有活跃的socket时,内核访问socket的callback(外部注入),不需要遍历轮询,但是当所有的socket都很活跃的时候,这时候所有的callback都被唤醒,会导致资源的竞争,既然要处理几乎所有的socket,那么,遍历是最简单有效的实现方式——select模型;

- epoll小结:

epoll的试用场景就是有大量的socket,但是活跃不是很高的情况;

// 仅仅是一个简单的,概念上的比较,后续会从代码层面深入理解;

参考:

http://www.cnblogs.com/Anker/p/3265058.html

http://blog.chinaunix.net/uid-20665047-id-3595356.html

0 0
原创粉丝点击