io模型

5 篇文章 0 订阅
1 篇文章 0 订阅

在这里插入图片描述

原图连接:https://download.csdn.net/download/qq_31443653/10707615

io

发起任务后,本身的一个状态

同步

异步

等待结果的过程中的状态

阻塞

非阻塞

处理请求的过程

服务器的网络驱动接收到消息,去内核上申请空间;并等待完整的数据包到达(有可能分组传送,没传完…),复制到内核空间;

数据从内核空间拷贝到用户空间

用户程序进行处理

5大网络模型(小红旗 餐馆排队)

同步阻塞IO

  • 排队的过程哪也去不了,如果你还没有带手机,排队的过程中就只能干瞪眼了

同步非阻塞

  • 如果小红旗的老板搞了一个点菜机,来点单的顾客把自己想吃的划上,然后等着老板去做,自己可以在这一个小时的时间里去周围商场溜达下。但是由于没有任何通信方式,只能不停的回来问老板,做好了没有。
  • 回来询问的时间是由顾客自己掌控的,如果时间很短,那么可以尽量早的知道臭豆腐炸好没,但是也会影响逛街的体验;如果时间很长,有可能臭豆腐早就做好了…结果放的时间长了,反而不好吃了。
  • 因此非阻塞IO基于状态轮训的方式,虽然能让程序在等待的过程中做点其他的事情,但是频繁的切换运行程序,反而会造成很大的压力。

IO多路复用/事件驱动

  • 小红旗老板升级了系统,放弃使用点菜机,改用麦当劳那种点餐大屏。同样是点餐,但是一个大屏里面显示了很多人的臭豆腐进度,即节省了资源,也避免大家不停的询问。
    • 其实Nio或者Netty就是基于这种模式,一个线程就可以监听很多IO操作,这样在IO等待上就高效多了。具体实现是依赖于操作系统的,windows和linux都有不同的实现方式。最初的select或者poll,都有并发数的限制,并且NIO的select还有空轮训的问题;epool则突破了连接数的限制,一个线程就可以监听大量的IO操作。这个感兴趣的朋友,可以深入了解下select、poll、epool的原理。
      • 都是IO复用,I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的
        • io触发 LT模式只要有事件未处理就会触发,而ET则只在高低电平变换时(即状态从1到0或者0到1)触发。
          • LT(level triggered)
            • 同时支持block和no-block socket内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你的
          • ET (edge-triggered)
            • 只支持no-block socket,当描述符从未就绪变为就绪时,内核通过epoll告诉你。然后它会假设你知道文件描述符已经就绪,并且不会再为那个文件描述符发送更多的就绪通知,直到你做了某些操作导致那个文件描述符不再为就绪状态了 (only once)
        • I/O多路复用
          • poll
          • select
            • 缺点
              • (1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
              • (2)同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大
              • (3)select支持的文件描述符数量太小了,默认是1024
          • epoll
            • epoll_create
              • 创建一个epoll的句柄
            • epoll_ctl
              • 它不同于select()是在监听事件时告诉内核要监听什么类型的事件,而是在这里先注册要监听的事件类型。
              • 每次注册新的事件到epoll句柄中时(在epoll_ctl中指定EPOLL_CTL_ADD),会把所有的fd拷贝进内核,而不是在epoll_wait的时候重复拷贝。epoll保证了每个fd在整个过程中只会拷贝一次。
              • poll_ctl时把current挂一遍(这一遍必不可少)并为每个fd指定一个回调函数,当设备就绪,唤醒等待队列上的等待者时,就会调用这个回调函数,而这个回调函数会把就绪的fd加入一个就绪链表
            • epoll_wait
              • 在这个就绪链表中查看有没有就绪的fd(利用schedule_timeout()实现睡一会,判断一会的效果,和select实现中的第7步是类似的)
            • 消息传递
              • 使用mmap加速内核与用户空间的消息传递
            • 它所支持的FD上限是最大可以打开文件的数目

信号驱动IO

  • 小红旗老板又时髦了,搞了一个升级版的美味不用等。顾客基于微信小程序点菜,菜做好了自动提醒顾客取餐…这个提醒的过程,就像是发射了一个特殊的信号。

异步非阻塞IO

  • 一对小情侣李雷和韩梅梅,韩梅梅口味很重,特别喜欢吃臭豆腐,但是李雷完全不感兴趣,闻到味道就想吐。于是李雷就跟韩梅梅约定,让韩梅梅自己去吃,李雷跑到旁边的咖啡厅喝咖啡。韩梅梅自己去排队买臭豆腐,买完顺便吃完,然后回来找李雷…
    • 这个过程就是异步非阻塞的,消息的等待和处理都在服务器端完成,用户只要最后接收到消息处理完的通知就行了。强调事情已经做完

nio

thread

  • selector
    • channel
      • buffer
        • capacity 容量
        • limit 剩余
        • position 位置
        • mark 标记位
        • flip(初始化为写模式,切换到读模式)
    • channel1
    • channel2

XMind: ZEN - Trial Version

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值