理解网络IO模型

Posted 计算机学习

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了理解网络IO模型相关的知识,希望对你有一定的参考价值。

上次我们讲了IO模型,这次我们来分析流行的IO复用模型的具体实现,先看select(基于linux kernel 4.1代码)。

0 调用关系

当userspace调到select系统调用后的调用关系:sys_select->core_sys_select->do_select->poll(此处的poll是指各个具体fd设备自定义的poll函数)。

我们依照调用关系看看。

1 sys_select

0)拷贝timeout结构体到kernel。

【拷贝操作,影响效率】

1)kernel据此计算出一个基于微秒级别的timeout值。

【微妙级别】

2)传入3个fd set和timeout调用core_sys_select,返回值是timeout还剩下的时间间隔。

【当然也可以不设置具体timeout,select会一直阻塞下去(直到有事件发生)】

3)拷贝剩下的时间间隔拷贝到userspace。

【拷贝操作,影响效率】

2 core_sys_select

0)在栈内分配一个long类型数组(含32个long,不够以后再动态申请)用于以bitmap形式存放6个fd set。

此处可见在fd数量大时会影响效率,每次select需要动态申请内存(每次都申请和释放)

1)获取进程的支持的打开fd的最大数量以控制扫描时的范围

【此处也体现效率低下,线性扫描范围的判断太简单】

2)kernel设置好6个fd set:in+out+exp+res_in+res_out+res_exp,其中前3个从userspace拷贝过来的。

【由于select入参只有3个fd set,既作入参也作出参,这也是引入userspace和kernel之间多次拷贝操作的原因;而kernel是直接使用6个fd set,不需要复用】

【6个fd set,每次select/poll都要以bitmap方式扫描,可见效率。。。】

【对于kernel而言,select支持的fd个数是可以改大的,只是改后影响效率而已】

3)调用do_select逐个处理每个fd set的每个fd,会调用到该fd的poll函数:


poll函数是该设备的具体实现,不管如何实现,都需要将代表本进程的poll_table结构(内嵌于poll_wqueues结构)挂入该fd的需要监测事件的等待队列里,如果发现监测事件是活跃的,则返回结果集。

【6个fd set(以bitmap形式)并行处理,这样直接掌控一个fd需要监测的所有事件(包括返回的结果集)。想想,这里仅是对一个fd的一次poll调用,但却是告知了该文件的所有需要监测事件】

这里传入具体设备poll函数里的wait参数是关键,其实就是一个poll_wqueues结构,该结构连接select/poll框架和具体设备的实现,该结构体管理了select/poll的所有监测fd的所有监测事件的等待队列里的元素(即poll_table_entry结构)。

【poll函数执行时的传入poll_table结构意味着该进程有可能在该fd的监测事件上睡眠。传入该结构体,就意味着poll函数可以通过该结构体分配的poll_table_entry结构去完成睡眠/唤醒的流程。

【并不是每个fd在其poll函数执行时都要传入poll_table结构的,有两种情况是例外的:一是当逐个扫描时已经发现有活跃事件了,后续的fd就不需要传入了;二是已经全部扫描一遍了,没有发现活跃事件(这样所有fd的poll函数其实都已经传入了)然后睡眠去了,之后再被唤醒后的重新扫描时不需要再传入了。

【poll函数每次传入poll_table结构体(select/poll虽然监测很多fd,但是其实是用的同一个poll_table结构体),该结构体的作用是分配poll_table_entry结构,分配的个数与fd的个数、fd的监测事件的个数成正比。如此多的poll_table_entry结构体的分配和释放在每次select/poll里都需要执行,可见效率。。。

每次select,需要遍历所有fd,对每个fd调用poll函数。这个遍历操作,在一次select里发生至少一次。

4.拷贝监测结果(即poll函数返回的结果集)给userspace

【拷贝操作,影响效率】

3 总结

总之select是IO复用模型的开山鼻祖(1983年bsd引入),年代久远,自然有些缺点(监控的fd个数越多,效率越低),后来的poll/epoll继续完善该模型,我们下次讲。。。(未完待续)

关于我们

新浪微博(@NP等不等于P

原创技术文章,感悟计算机,透彻理解计算机!

文完,谢谢阅读!



以上是关于理解网络IO模型的主要内容,如果未能解决你的问题,请参考以下文章

理解网络IO模型

通过实例理解Java网络IO模型

通过实例理解Java网络IO模型

编程基础心法「IO模型原理分析」彻底明白网络IO模型的原理(夯实基础)

梳理IO网络模型

从实践中理解IO模型