Linux下的多路复用 - Xinrea/Learn GitHub Wiki
Linux下多路复用IO接口epoll/select/poll
Select
1.Socket数量限制:该模式可操作的Socket数由FD_SETSIZE决定,内核默认32*32=1024.
2.操作限制:通过遍历FD_SETSIZE(1024)个Socket来完成调度,不管哪个Socket是活跃的,都遍历一遍.
基本用法
- fd_set set;
- FD_ZERO(&set); /* 将set清零 */
- FD_SET(fd, &set); /* 将fd加入set */
- FD_CLR(fd, &set); /* 将fd从set中清除 */
- FD_ISSET(fd, &set); /* 如果fd在set中则真 */
int select(int nfds, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout);
其中:
nfds
:需要检查的文件描述符个数,数值应该比是三组fd_set中最大数更大,而不是实际文件描述符的总数。
readset
:用来检查可读性的一组文件描述符。
writeset
:用来检查可写性的一组文件描述符。
exceptset
:用来检查意外状态的文件描述符。(注:错误并不是意外状态)
timeout
:NULL指针代表无限等待,否则是指向timeval结构的指针,代表最长等待时间。(如果其中tv_sec和tv_usec都等于0, 则文件描述符的状态不被影响,但函数并不挂起)
Poll
1.Socket数量几乎无限制:该模式下的Socket对应的fd列表由一个数组来保存,大小不限(默认4k).
2.操作限制:同Select.
Epoll
1.Socket数量无限制:同Poll
2.操作无限制:基于内核提供的反射模式,有活跃Socket时,内核访问该Socket的callback,不需要遍历轮询.但是当所有Socket都活跃的时候,这时候所有的callback都被唤醒,会导致资源的竞争.既然都是要处理所有的Socket,那么遍历是最简单最有效的实现方式.