form select multiple 某个字段是数组_select、poll、epoll

网络连接在内核中是以文件描述符fd来表示的

d5208784f208a5dde57cffc0428c403c.png
while(1){
    for(Fdx in (FdA ~ FdE)){
        if(Fdx 有数据){
            读取Fdx的数据并进行处理
        }
    }
}
简单粗暴解决问题

缺点:判断是否有数据是由程序判断的,效率较低

select

618779cc97b6784e425f3eeb13fbe65d.png
准备文件描述符的数组fds
dfs中的每个元素其实是一个数,这个数代表着文件描述符的编号,这个编号并不是按顺序的可能是随机的数
将最大的文件描述符存入到max中

select(最大文件描述符+1,读文件描述符集合,写文件描述符集合,异常文件描述符集合,超时时间)

读文件描述符集合是一个bitmap,用来表示哪一个文件描述符是被启用的(被监听的),默认1024个位
例如存入的文件描述符为:1 2 5 7 9
那么bitmap的存储为:0 1 1 0 0 1 0 1 0 1
即bitmap中涵盖的fdx的所有信息

select执行流程

程序是运行在用户态空间的,但是select将用户态的rset拷贝到内核态,由内核态判断每一个fdx是否有数据来

d7fd111916d5b1975d8dd94f8c5ccc06.png

如果没有数据,那么内核态就一直在这判断,程序呈一个阻塞状态,即select是一个阻塞函数如果没有任何数据到来那么程序将会一直阻塞在select

当有数据到来时

  1. 内核将会再有数据的FD置位
  2. select返回
  3. 遍历FD,判断哪一个FD被置位,将置位的FD读出进行相应的处理

总结:我们将文件描述符收集过来,交给内核,让内核帮我们判断哪一个有数据,当里面任何一个或多个有数据的时候,select函数会返回,并且有数据的fd会被置位,返回之后fd集合,判断一下到底哪一个被set了,即被set的是有数据的,这个时候我们读取fd中的数据,并进行相应的处理,提高效率最主要的一点就是,他将fd放到了内核态,让内核帮我们判断哪一个fd有数据。

缺点:

  1. fd的大小为1024,虽然可以调整大小,但依然是有上限的
  2. 在判断置位后,fd的数据被修改,所以在此循环是需要将bitmap重新置位
  3. 虽然比每次用户态切换到内核态好一些,但将rset拷贝到内核态依然有很大的开销
  4. select函数返回时,我们知道有位被置位,但是不知道哪一个位被置位,需要再次遍历一遍,O(n)复杂度

poll

f09cd9cd6025165d5dd4e2eb7fe428e1.png

poll(pollfd结构体的数组,pollfd数组有几个元素,超时时间)

poll的工作原理和select相同

b02b5ebb5f6465e591e54ab95c09a4be.png

pollfd结构体:

  1. fd:文件描述符
  2. event:在意的事件(读时间、写事件)
  3. revents:对event的回馈

当有数据时

  1. 将fd置位:将pollfd中的revents字段置位
  2. poll返回
  3. 判断revents是否有数据,进行数据的读取和处理(revents置位,可重用)

poll解决了select的缺点:1、2、

epoll

75ff60019b8965e7cd58016d1e8f3e5c.png
epoll_create:创建epfd(epollfd)(理解成创建白板)

4bc02ea60bce8313dd5df9118f126298.png

epoll_ctl:对epoll进行配置,相当于在白板上写字

aee3fc2bc21ea02e2adc2959f545ade5.png
EPOKK_CTL_ADD:加一行字
ev.data.fd:文件描述符
ev:对应的事件

epoll中的结构体是epoll_event格式,其同样拥有fd和event,但是没有revents字段

d49a917bbc3588043af738928e0c26a4.png

epoll_wait:

用户态和内核态共享epfd

b3f35c32cd813ac9b9514b1b81a847ed.png

解决了缺点(3)

epoll_wait也是阻塞状态的(水平触发),当有数据时

  1. 置位,通过重排,把有数据的重排至前面

3ee889acd57e2453a5be470bb0dc0bab.png

2. 返回,值为一共有多少个FD触发了事件,按照此例题,则返回3,所以复杂度为O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值