石家庄门户网站建设,公司网页制作官网,济宁专业网站制作公司,wordpress注册授权一、 select
最low的就是在用户代码中自旋实现所有阻塞socket的监听。但是每次判断socket是否产生数据#xff0c;都涉及到用户态到内核态的切换。 于是select改进#xff1a;将fd_set传入内核态#xff0c;由内核判断是否有数据返回#xff1b;
然后最low的只能使用自旋…一、 select
最low的就是在用户代码中自旋实现所有阻塞socket的监听。但是每次判断socket是否产生数据都涉及到用户态到内核态的切换。 于是select改进将fd_set传入内核态由内核判断是否有数据返回
然后最low的只能使用自旋来时刻的去判断socket列表中是否有数据达到。 于是select改进使用等待队列让线程在没有资源时park阻塞当有数据到达时唤醒select线程去处理socket。 缺点 二、epoll
epoll是在select出现N多年后才被发明的是select和poll的增强版本。epoll通过以下一些措施来改进效率。
措施一功能分离
select低效的原因之一是将“维护等待队列”和“阻塞进程”两个步骤合二为一。如下图所示每次调用select都需要这两步操作然而大多数应用场景中需要监视的socket相对固定并不需要每次都修改。epoll将这两个操作分开先用epoll_ctl维护等待队列再调用epoll_wait阻塞进程。
int s socket(AF_INET, SOCK_STREAM, 0);
bind(s, ...)
listen(s, ...)int epfd epoll_create(...);
epoll_ctl(epfd, ...); //将所有需要监听的socket添加到epfd中while(1){int n epoll_wait(...)for(接收到数据的socket){//处理}
}
措施二就绪列表
select低效的另一个原因在于程序不知道哪些socket收到数据只能一个个遍历。如果内核维护一个“就绪列表”引用收到数据的socket就能避免遍历。如下图所示计算机共有三个socket收到数据的sock2和sock3被rdlist就绪列表所引用。当进程被唤醒后只要获取rdlist的内容就能够知道哪些socket收到数据。
三、对比