00:00
各位同学大家好,我们继续,那么接下来理论说完了。落地的函数,咱们唠唠,注意这个就是Linux底层内核的函数,不是我写的啊,咱们来看一遍它怎么点滴进化,最后是到我们的一泡好。首先C语言的结构体不多说了,来吧,先来一个最早诞生的,最先出现的select方法来,首先弟兄们。Linux官网或者我们的may命令啥意思呢?请看啊,它这是有这么一个select函数,那杨哥这哪来的,那么大家都清楚,在Linux世界里面,如果我不会哪一个命令,我是不是可以用man有问题问男人对吧,请大家看man,然后呢,是我们的select大二级啊,那么这就说明什么是Linux系统内核的对吧?所以说呢,命令长这么长,哎,来看看吧,啥意思,12345来吧,在这块。
01:16
NFDS监控的文件描述符里,最大文件描述符夹击啊,后面我们会看源码,什么叫夹击啊,它为了保证都能取到,不会扑空给你多一个。比如我请八个人吃饭,我准备了九份饭菜。那么这个呢,挨个过来,它呢是监控有读数据到达文件的描述符集合传入传出参数来,这个是监控什么写数据的读写,这个是监控exception异常发生的文件描述符好,这个呢干嘛?定时阻塞监控时间,那么在这块它有三种情况,123,这个永远等,这个等待固定时间,这个呢,时间均为零,检查描述,检查描述字后立刻返回是轮巡,那么所以说select函数监视的文件分为分别是读写和异常,将用户传入的数组拷贝到内核空间,调用后select函数和阻塞,直到有描述符就是。
02:24
杨哥还有点听不懂说什么话,将用户传入的速度拷贝到内核空间,哎,注意,就是将本次参加考试的所有考生弄到监考老师名下,那么然后调用监考老师啊,开始监考,那学生在写卷子啊,监考老师在讲台上看着我,是不是就阻塞了,直到有描述符就去哪个考生举手老师。我上个厕所,或者我要交卷了,OK或者超时等等,那么这个时候单select函返回后,可以通过便利f set这个集合来找到就绪的描述符,注意它还是通过什么啊变列好了,我们这个函数我们了解来漏首先啊,这个呢是在我们操作系统里面的,如果你嫌这不好,看来弟兄们我们再打开我们对应的。
03:17
命令的官网,那么Linux这样的一个也是跟那个内部的差不多啊,Main命令在这儿你就给你写着了,每一个参数大概是什么意思,有兴趣的你可以读一下,那看一眼这个Linux内核的系统级的这个select函数是在什么时候,1983年左右就已经有了,也是40年前的东西啊,现在还在用,所以说同学们什么操作系统啊,内核底层这些东西不变的啊。可以这么讲,就是计算机不变的,也就是20%,什么算法,函数结构,操作系统啊等等脱离不了,你先告诉我,就比如说你现在这个东西要不要装到Linux啊,你躲不掉,那表面上什么阿里云,那什么这的底层还是这些东西,所以说人话,那么咱们呢,就是用户他我们自己写的Java代码的思想啊,你如说把这段给我塞进内核里面,也就说这种思想,当然啊,大神写的肯定要比杨哥写的要我这用Java写这个,就是说这个思想他们用底层优化的好,给我封装进了select函数,就这么简单,所以兄弟们我们来看一下select它怎么干的来啊,那么在这块稍微有点晦涩,同学们跟着我走一遍就行了,不要求大家完全掌握啊,就当是一个知识的了解面试啊,足够大家说现在哎,我多了复用了,那么首先这个s select函数这样题它是一个阻塞函数啊,监考老师站在讲台上监听了,当没有数据的时候,会一直阻塞在s select内行,当没有学生举手的时候,监考老师一直站在讲台上。
04:45
看着监听,当有数据时,会将reet中对应的那一位置为一,比如说,哎,第三排靠近窗边的第五个学生举手了,老师要交卷了,那么我下去就去找,那么select函数返回,我就不再阻塞了。便历文件描述数组判断哪个FD被自位了,哎,就是哪个人有读写准备要举手了。
05:08
读取数据,然后交给内核进行处理好整个流程就那么五步,来吧,来看一下它底层写的。第一组socket fd,那么就是那些连接套接字啊,这些些底层的,你不用竹行搞懂,大致了解就行了,那么来这块弟兄们请看是不是有什么绑定,是不是有什么监听,说人话就是我们上面这些什么绑定啊,在哪个地址,哪个IP,哪个端口上监听着这么一个监考老师站哪去这个缩的连接展歌断带了,OK,准备要建立起来,好了,那么现在我们这为了讲课方便啊。模拟五个客户端连上来了,请看分配内存,然后呢,这个时候请看这是不是有个except,这个时候就监听过来,这这个so知道了,有五个过来纷纷装到我们这个数组里面,是不是有点类似于我们这个动的啊,没问题吧,那么给你一个FD,别忘了啊,我们在这select方法的或在这是不是有监控的文件描述符这个集合里面,对吧?那么现在写了个集合,那么大致呢,只有五个人好吧,塞进来,那么FD大于max max呢,就只为这个找到一个最大的描述文件描述符,如果咱这块,那么主要这是给它的数字加个一,不让它扑空,好那么接下来Y有一,那么C语言里面Y有一,是不是相当于我们加va里面的Y要错来吧,那们同学们漏一这个开始啊,五个。
06:45
这波你可以听好,这个有点像我们red里面的那个bit map,它是这样的啊,便利循环,那么如果五个文件描述符啊,最后给它的一个分配是012。12457,那么从这个位置啊,它加了个一啊,那么相当于说12457,那么这个bit map就说比如说我们这个教室里面一号位,二号位,四号位,五号位,七号位有有的地方我这个bit map给你分配一块010101,那么大家请看零对零,一号位有一就是一,二号位要有,那么这就是个一,就像是第二天你登录了,就只为一,三号位没有就是零,四号位有就是一,听懂了吧,就是这是一个随机的,不一定是这我只是为了讲课方便就模拟啊,比如说在这块fd set。
07:35
听懂了吧,那么相当于说我们塞进去这五个给你。撒过去,电影院里面有一排座位,你爱坐哪一个?只要是被抢到的座位就置唯一,类似于bit map。好,那么接下来请看。中间这块put round again,再来一次,那这个时候干嘛?Select markx夹击前面那个数字我说过了,为了保证你取得最完整的数据,不要扑扣多一位,把上面这些治好的塞过来,就这个bit map,那select是一个系统调用,它会堵塞,直到有数据发送到这个socket,这也就是我们连上来了这五个,谁先有这个命令或者动作,那么我们检测到select,就会把这个呢相应的位置只问,哎,比如说这个对吧,假设。
08:23
是四号,So,他写了个set k为一,那么呢,这个时候干嘛我呢就会有异动,那么就会把相应的位置置位,但并不会返回是哪个索给它有数据啊,那么接下来看又变列。用户态开始搁到这儿,Member set,那么在这儿读取来你对应的数据,然后把它打到八法里面,那么用户态只要便利这个就OK,看哪一位被置位了,不需要每次调用系统调用来判断,哎,我只看第三排第五个,有人举手我就去找他就行了,效率就大大提升,便利到被职位的文件描述符就进行读取,OK,所以在这块就是我们这五步的一个步骤的一个参考。那么这种方法它的优点和缺点分别是什么呢?来先说优点啊,说人话,这段代码前面说过了,就是把我们自己写的NIO单招铺态要便利的FD数组,我们的每一个socket连接安装进I里面,那个拷贝到了内核态,让内核态里面来变列,哎,因为用户判断soet是否有数据。
09:39
还是要调用内核态,所有拷贝到内核态以后,这样便利判断的时候就不用一直用户态和内核态频繁切换了,让内核去做打包封装进我们的select,那么我们从代码这这一小段就可以看出。S select系统调用之后返回了一个置位后的这么一个reset,这样用户态只需要进行很简单的二进制,比较零没有一,有点类似于考生举手了,这样就很快会知道哪些socket需要读数据,有效提高了我们的效率好。那么下面虽然是这么好,那为什么还会有后面这两个呢?那么它的缺点是什么呢?
10:25
来请看select呢?这个函数的缺点,它是通过质问便利实质而言。是个bit map,但是在这套函数由于它是1983年啊就出版的,它的默认大小1024虽然可以调整,但是还是有限度的,那么如果超过1024呢?那么这个时候select函数它的使用上限是不是就被约束了?第二个呢,Reet每次循环都必须重新置位为零,难以复用。第三一个,尽管已经是从用户态拷贝到内核态了,内核态判断是否有数据还是有拷贝的开销。最后一个,当有数据时,Select就会返回,但是select函数并不知道是哪个文件描述会有数据。
11:16
后面还需要再次文件描述符进行并列,效率还是有点低,所以这个时候我们呢,一二两个好理解,现在就是select函数有这四个毛病,后面是不是挨个挨个尽量的把这四个。解决掉,那么最后导出我们的一泡函数,最啰嗦的就是三和四,笔记在这儿我就不再啰嗦。我们自己模拟写的这个write server IO,实质而言就是讲我们这段代码将其内核化,OK好。所以说同学们对于select函数小结就一句话,他就做到了一个线程处理多个客户端,连接多个F点,减少了系统调用的开销。那么多个文件描述符只有一次select的系统调用,加多次就绪状态文件描述符的read系统调用,这个就是我们的select方法。
我来说两句