「操作系统」五种IO模型 零拷贝

  • 内核态与用户态

    1. 内核态: 可以访问系统资源, 比如CPU, 内存, 网络, 外设

    2. 用户态: 只能访问进程自己的资源, 无法访问系统资源

    3. 用户态需要访问系统资源时, 需要CPU切到内核态, 读取资源后再切回用户态. 中间涉及堆栈上下文的切换, 为避免频繁切换, 有了"用户缓冲区"和"系统缓冲区".

    4. 当用户进程需要从"磁盘/网络"中读取数据时, 系统会将"系统缓冲区"的数据复制到"用户缓冲区". 若"系统缓冲区"中没有对应数据, 系统会将当前进程挂起, 处理其他进程. 等数据到达"系统缓冲区"后, 系统将数据拷贝至"用户缓冲区", 然后才会通知进程, 注意不同IO模型方式不同.

  • 五种IO模型, IO即磁盘/网络读写

    1. c10k 一台计算机实现10000台客户端的连接, 并处理对应的请求. 一个进程处理一个连接, 会消耗过多资源. 所以要一个进程处理多个连接, 即IO多路复用, 目前通过IO多路复用已实现c10k.

    2. 五种IO模型 (参考自https://zhuanlan.zhihu.com/p/54580385)

      1. 所有的IO模型都分为两阶段, 前四个模型, 第二阶段复制数据阶段都是阻塞的.

        1. 等待系统将数据准备好, 即等待数据从网卡/磁盘复制到"系统缓冲区"

        2. 将数据从"系统缓冲区"复制到"用户缓冲区"

      2. 阻塞式IO, 第一阶段"请求进程"调用receive, 一直阻塞至第二阶段完成

      3. 非阻塞IO, 第一阶段"请求进程"不停调用receive, receive立即返回异常. 直至"数据已备好"后, "请求进程"再调用receive会阻塞至第二阶段完成

      4. IO多路复用(即事件驱动), 第一阶段"请求进程"调用select, 并阻塞至"数据准备好". 第二阶段"请求进程"发起receive, 阻塞至拷贝完成. 虽然看起来"请求进程"都是阻塞, 但是服务器内核可以同时监听select负责的多个套接字, 服务器效率非常高

      5. 信号驱动IO, 第一阶段"请求进程"向内核注册信号后, 不阻塞. 当"数据准备好"后, 内核通过信号通知"请求进程", "请求进程"调用receive, 阻塞取得数据

      6. 异步IO, 第一阶段"请求进程"发起receive, 不阻塞. 当第二阶段数据拷贝完后, 内核会通过回调通知"请求进程".

    3. nginx是事件驱动服务器的代表, 适合IO密集型服务, 使用的是epoll; Apache是线程服务器的代表, 适合计算密集型服务(apache存疑)

    4. select, poll, epoll

  • 零拷贝 (参考自https://juejin.im/post/6844903949359644680)

    1. 当用户进程通过网络发送磁盘数据时, 依次调用read和send.

      1. 调用read时, 首先内核会检查"系统缓冲区"有无缓存, 若没有, 会通过DMA将数据从磁盘拷贝到"系统缓冲区". 然后通过CPU将数据从"系统缓冲区"拷贝到"用户缓冲区".

      2. 调用send时, 通过CPU将数据从"用户缓冲区"拷贝到套接字的"系统缓冲区", 再由套接字的"系统缓冲区", 通过DMA拷贝到网卡中, 发送出去.

      3. 总体上经过4次内核态与用户态的上下文切换, 2次CPU调用, 2次DMA调用

    2. 零拷贝优点

      1. 减少数据在"用户缓冲区"与"系统缓冲区"间的拷贝

      2. 减少数据拷贝时, "用户态"与"内核态"的上下文切换

    3. 实现方式

      1. 用mmap+send代替的read+send, mmap可将指定的"系统缓冲区"对用户进程共享, 从而避免CPU将数据从"系统缓冲区"拷贝到"用户缓冲区", 因此也不存在send时CPU将数据再从"用户缓冲区"拷贝到"系统缓冲区", 但会多1次从"系统缓冲区"到套接字的"系统缓冲区"的CPU拷贝, 故整体少了1次CPU拷贝. 总体上4次上下文切换, 1次CPU调用, 2次DMA调用

      2. 用sendfile代替read+send, 也是减少1次CPU拷贝, 但因为数据可以直接在内核空间传输, 故减少2次上下文切换. 总体上2次上下文切换, 1次CPU调用, 2次DMA调用

      3. 用splice代替read+send, 通过在"系统缓冲区"与套接字的"系统缓冲区"间建立管道, 完全避免了CPU拷贝. 总体上2次上下文切换, 0次CPU调用, 2次DMA调用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值