还在持续学习中,本文是一个阶段性的总结。html
select的核心是不停的遍历文件描述符,看看是否就绪。通常最多同时支持1024个文件描述符。函数
int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
- nfds:最大的文件描述符加1
- readfds:监听可读集合
- writefds:监听可写集合
- exceptfds:监听异常集合
- timeout:超时时间
唤醒 当前进程的过程一般是在所监测文件的设备驱动内实现的,驱动程序维护了针对自身资源读写的等待队列。当设备驱动发现自身资源变为可读写而且有进程睡眠在该资源的等待队列上时,就会唤醒这个资源等待队列上的进程。性能
select随着文件描述符数量的上升,性能会急剧降低学习
poll的总体流程和select差很少,也是每次遍历全部文件描述符,性能很差,不过poll解决了select文件描述符数量的限制问题。ui
select和poll运行效率的两个瓶颈已经找出,如今的问题是怎么改进。.net
epoll总共提供了三个函数unix
int epoll_create(int size);
epoll_create是为了建立一个epoll文件描述符,新建立的epoll文件描述符带有一个struct eventpoll结构,eventpoll结构以下。code
struct eventpoll { spinlock_t lock; struct mutex mtx; wait_queue_head_t wq; /* Wait queue used by sys_epoll_wait() ,调用epoll_wait()时, 咱们就是"睡"在了这个等待队列上*/ wait_queue_head_t poll_wait; /* Wait queue used by file->poll() , 这个用于epollfd本事被poll的时候*/ struct list_head rdllist; /* List of ready file descriptors, 全部已经ready的epitem都在这个链表里面*/ struct rb_root rbr; /* RB tree root used to store monitored fd structs, 全部要监听的epitem都在这里*/ epitem *ovflist; /*存放的epitem都是咱们在传递数据给用户空间时监听到了事件*/. struct user_struct *user; /*这里保存了一些用户变量,好比fd监听数量的最大值等*/ };这个结构上再挂一个红黑树,而这个红黑树就是每次epoll_ctl时fd存放的地方。htm
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
此函数是添加、删除、修改事件blog
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
此函数是等待条件知足,返回值为准备就绪的事件数
【参考】
1.http://www.javashuo.com/article/p-txmndpyl-cm.html
2.https://blog.csdn.net/weixin_42462202/article/details/95315926
3.https://blog.csdn.net/turkeyzhou/article/details/8609360
4.http://blog.chinaunix.net/uid-20643761-id-1594860.html
5.http://blog.chinaunix.net/uid-28541347-id-4236779.html
6.http://blog.chinaunix.net/uid-28541347-id-4238524.html