1

I/O模型-读书笔记

 3 years ago
source link: https://blogread.cn/it/article/3305?f=hot1
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

I/O模型-读书笔记

浏览:6547次  出处信息

    I/O模型:

    I/O操作需要内核系统调用来完成,系统调用需要Cpu来调度,而Cpu的访问速度相对于I/O来说比较快,所以Cpu不得不浪费Cpu时间来等待慢速I/O操作.

    通过多进程方式来充分利用CPU资源,当还是希望让Cpu花费少的时间在I/O操作的调度上,这样就可以有更多的Cpu来完成I/O操作.

    很多技术和策略都围绕如何让高速的Cpu和慢速的I/O设备更好的协调工作.

    I/O操作主要是网络数据的接收和发送,以及磁盘文件的访问.归纳为多种模型称为I/O模型,本质区别在于Cpu的参与方式.

    PIO和DMA:

    慢速I/O设备和内存之间传输方式

    PIO:磁盘和内存之间的数据传输需要Cpu控制,读取磁盘文件到内存的时候,数据需要经过Cpu存储转发.

    DMA:可以不经过Cpu而直接进行磁盘和内存的数据交换,DMA模式下,Cpu只要向DMA控制器下达指令,让DMA控制器来处理数据的传输即可.DMA控制器通过系统总线来传输数据,传输

    完毕后再通知Cpu.这样减低了Cpu占有率.

    同步阻塞I/O:

    I/O等待例子很多,比如web服务器等待用户请求.比如服务器与浏览器建立TCP链接后,需要等待用户发送HTTP请求.

    I/O等待不可避免,有等待就会有阻塞.阻塞指的是当前发起I/O操作的进程被阻塞,并不是Cpu被阻塞,实际上没有什么能让Cpu阻塞,它只知道干活.

    同步阻塞I/O指当前进程调用I/O操作的系统调用或者库函数时候,比如accept,send,recv等,进程便暂停,等待I/O操作完成后再继续运行.这样的I/O模型可以和多进程结合有效利用Cpu资源.

    同步非阻塞I/O:

    在同步阻塞I/O中,进程实际上等待的时间包括二部分,一个是等待数据的就绪,另外一个是等待数据的复制.对于网络I/O来说,前者的时间可能更长.

    同步非阻塞I/O的调用不会等待数据的就绪,如果数据不可读写,则立即告诉进程.这种非阻塞I/O结合反复轮询来尝试数据是否就绪,防止进程被阻塞.最大的好处便在于可以在同一个进程里

    同时处理多个I/O操作.但是由于一直在多次轮询查看数据是否就绪,花费大量Cpu时间.非阻塞I/O一般只针对网络I/O有效,对于磁盘I/O非阻塞I/O不产生效果.

    多路I/O就绪通知:

    web服务器同时处理大量文件描述符必不可少.由于要对socket检查是否可以接收的数据,则会浪费太多的Cpu时间.

    多路I/O就绪通知出现,提供了对文件描述符就绪检查的高性能方案.允许进程通过一种方法来同时监视所有文件描述符.并可以快速获得所有就绪的文件描述符.然后只针对这些描述符进行数据访问.

    I/O就绪通知只是帮助快速获得就绪的文件描述符.当得知数据就绪后,就访问数据本身而言.仍然需要选择阻塞和非阻塞的访问方式.多路I/O就绪通知有多种实现.

    select:

    通过一个select系统调用来监视包含多个文件描述符的数组.当select返回后,该数组中就绪的文件描述符会被内核修改标志位.使得进程可以获得这些文件描述符从而进行读写操作.

    select的缺点

    1)单个进程能够监视的文件描述符的数量存在最大限制.

    2)select维护的存储大量文件描述符的数据结构,随着文件描述符量的增大,复制的开销也线性增长.

    3)网络响应时间的延迟使得大量Tcp链接处于非活跃状态,但是select会对所有socket进行一次性扫描,也浪费了一定开销.

    poll:

    没有最大文件描述符的限制.select和poll将就绪的文件描述符告诉进程后,如果进程没有对其进行I/O操作,下次调用select和poll的时候将再次报告这件文件描述符.所以不会丢失就绪的

    消息,该方式称为水平触发.

    sigio:

    sigio不是每次都告诉我们文件描述符是否就绪,而是高速文件描述符刚刚变为就绪,只说一次,称呼为边缘触发.

    /dev/poll:

    使用虚拟的/dev/poll设备,可以将有监视的文件描述符数组写入这个设备,然后通过ioctl来等待时间通知.没有提供直接的内核支持,所以性能不是很稳定.

    /dev/epoll:

    在/dev/epool的基础上增加了内存映射.

    epoll:

    本质的改进是epoll基于事件的就绪通知,通过callback的机制来激活文件描述符.

    内存映射:

    linux内核提供一种访问文件的特殊方式.可以将内存中某块地址空间和制定的磁盘文件相关联.从而对这块内存的访问转换为对磁盘文件的访问.

    大部分情况下,使用内存映射可以提高磁盘I/O访问的性能,因为无须read或者write系统调用,而是通过mmap系统调用建立内存和磁盘文件的关联,然后像访问内存一样只有访问文件.

    直接I/O:

    linux2.6中,内存映射和直接访问文件没有本质区别.因为数据从进程用户态内存空间到磁盘需要经过二次复制,及在磁盘与内核缓存区之间以及在内核缓存区与用户态内存空间.

    引入内核缓存区的目的在于提高磁盘文件的访问性能.比如进程读取磁盘文件的时,如果文件已经在内核缓冲区中,那么就无须再访问磁盘.而进程需要向文件中写入数据的时候.则

    直接写到内核缓存区便告诉进程已经成功写入,写入磁盘是通过一定策略进行延迟.

    为了充分提高性能,系统绕过内核缓存区,由自己在用户空间实现管理I/O缓存区,比如数据库的缓存机制和写延迟机制.

    Linux提供了对这种需求的支持,在open系统调用的时候增加参数选项O_DIRECT.用它打开的文件便可以通过内核缓存区的直接访问,有效避免了Cpu和内存的多余时间开销.

    Sendfile:

    引入Sendfile在于内核希望请求的处理尽量在内核完成,减少内核态的切换以及用户数据复制的开销,Linux通过系统调用提高这种机制,它可以将磁盘文件的特定部分直接传送到客户端的Socket

    描述符,所以一般使用在网卡传输,减少cpu和内存的开销.

    异步I/O:

    同步和异步,阻塞和非阻塞容易被混用,其实完全不一样,修饰的对象也不同.

建议继续学习:

QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK