Linux-I/O多路复用原理(select,poll,epoll)

Linux-I/O多路复用(select,poll,epoll)

select

函数原型

select系统调用会阻塞进程,当有数据到来系统将fd_set对应位置位,select函数返回.select会将fd_set拷贝到内核.其实select只能返回一个准备好的文件描述符,如果在主线程对相应的文件描述符做操就会阻塞,使得其他准备好的文件描述符得不到处理,因此就有了Reactor模型.

#include <sys/select.h>
 
int select(int nfds, fd_set *rdfds, fd_set *wtfds,
                fd_set *exfds, struct timeval *timeout)

缺点

  • fd_set组成的bitmap只有1024个
  • fd_set不可重用,每次都要重新设置fd_set
  • 拷贝fd_set有开销
  • 需要遍历fd_set

poll

函数原型

poll使用了pollfd结构体,有数据到来系统将polfd.revents置位

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

对select改进

  • 使用pollfd数组,可以管理大于1024个文件描述符
  • pollfd可重用
  • 遍历范围变小(pollfd数组),poll返回准备好的文件描述符个数

epoll

函数原型

有数据到来系统将epfd用重排来置位(将有数据的epfd放在数组前面)

//创建size个监听,返回一个红黑树的文件描述符epfd
int epoll_create(int size)
//epfd控制
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
//等待epfd准备好
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)

使用以下命令查看可以使用的pollfd数量

cat /proc/sys/fs//file-max

改进

  • epfd用户态与内核态共用
  • 遍历范围变小(准备好的epfd数组),epoll_wait返回准备好的文件描述符个数

触发模式

  • 边沿触发(ET):文件描述符从无数据状态到有数据状态epoll才触发
  • 水平触发(LT):文件描述符有数据epoll就触发

应用

  • redis
  • nginx
  • java NIO(Linux系统)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章