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是活跃的,都遍历一遍.

基本用法

  1. fd_set set;
  2. FD_ZERO(&set); /* 将set清零 */
  3. FD_SET(fd, &set); /* 将fd加入set */
  4. FD_CLR(fd, &set); /* 将fd从set中清除 */
  5. 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,那么遍历是最简单最有效的实现方式.