Gitlib Gitlib
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)

Ravior

以梦为马,莫负韶华
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)
  • 操作系统

  • 计算机网络

    • 深入理解IO模型
      • 名词解释
        • 同步
        • 异步
        • 阻塞
        • 非阻塞
      • IO模型
        • 阻塞IO模型
        • 非阻塞IO模型
        • IO复用模型
        • 信号驱动IO模型
        • 异步IO模型
    • DDOS攻击下多IP防御思路
    • 从TCP/IP协议谈Linux内核参数优化
    • IO多路复用之select、poll、epoll详解
  • 数据结构和算法

  • MySQL

  • Redis

  • Nginx

  • MongoDB

  • 其他

  • 计算机基础
  • 计算机网络
Ravior
2019-07-23
目录

深入理解IO模型

关于IO模型,就必须先谈到几个日常接触的几个与IO相关名字:同步,异步,阻塞,非阻塞。

# 名词解释

# 同步

如果事件A需要等待事件B的完成才能完成,这种串行执行机制可以说是同步的,这是一种可靠的任务序列,要么都成功,要么都失败。

# 异步

如果事件A的执行不需要依赖事件B的完成结果,这种并行的执行机制可以说是异步的。事件A不确定事件B是否真正完成,所以是不可靠的任务序列。

同步异步可以理解为多个事件的执行方式和执行时机如何,是串行等待还是并行执行。同步中依赖事件等待被依赖事件的完成,然后触发自身开始执行,异步中依赖事件不需要等待被依赖事件,可以和被依赖事件并行执行,被依赖事件执行完成后,可以通过回调、通知等方式告知依赖事件。

# 阻塞

对于阻塞,如果一个事件在发起一个调用之后,在调用结果返回之前,该事件会被一直挂起,处于等待状态。

# 非阻塞

对于非阻塞,如果一个事件在发起调用以后,无论该调用当前是否得到结果,都会立刻返回,不会阻塞当前事件。

阻塞与非阻塞可以理解为单个事件在发起其他调用以后,自身的状态如何,是苦苦等待还是继续干自己的事情。非阻塞虽然能提高CPU利用率,但是也带来了系统线程切换的成本,需要在CPU执行时间和系统切换成本之间好好估量一下。

# IO模型

IO模型分为五种,阻塞IO模型、非阻塞IO模型、IO复用模型、信号驱动IO模型、异步IO模型、前4种为同步IO操作、只有异步IO模型是异步IO操作、请仔细阅读IO交互便于理解IO模型。

# 阻塞IO模型

网络编程中,读取客户端的数据需要调用recvfrom。在默认情况下,这个调用会一直阻塞直到数据接收完毕,就是一个同步阻塞的IO方式。

I/O

模拟举例:

老李去火车站买票,排队三天买到一张退票。 耗费:在车站吃喝拉撒睡 3天,其他事一件没干。

# 非阻塞IO模型

当用户进程发出read操作时、如果内核中的数据还没有准备好、那么它并不会阻塞用户进程、而是立刻返回一个error、从用户进程角度讲、它发起一个read操作后、并不需要等待、而是马上就得到了一个结果、用户进程判断结果是一个error时、它就知道数据还没有准备好、于是它可以再次发送read操作、一旦内核中的数据准备好了、并且又再次收到了用户进程的系统调用、那么它马上就将数据拷贝到了用户内存、然后返回。

非阻塞的接口相比于阻塞型接口的显著差异在于在被调用之后立即返回,在非阻塞式IO中,用户进程其实是需要不断的主动询问kernel数据准备好了没有。

I/O

模拟举例:

老李去火车站买票,隔12小时去火车站问有没有退票,三天后买到一张票。 耗费:往返车站6次,路上6小时,其他时间做了好多事。

# IO复用模型

如果一个I/O流进来,我们就开启一个进程处理这个I/O流。那么假设现在有一百万个I/O流进来,那我们就需要开启一百万个进程一一对应处理这些I/O流(——这就是传统意义下的多进程并发处理)。思考一下,一百万个进程,你的CPU占有率会多高,这个实现方式及其的不合理。所以人们提出了I/O多路复用这个模型,一个线程,通过记录I/O流的状态来同时管理多个I/O,可以提高服务器的吞吐能力。

IO复用模型的本质是同步非阻塞I/O,多路复用的优势并不是单个连接处理的更快,而是在于能处理更多的连接

IO复用是多了一个select函数,select函数有一个参数是文件描述符集合,对这些文件描述符进行循环监听,当某个文件描述符就绪时,就对这个文件描述符进行处理。

I/O

目前支持多路复用的系统调用有select, poll, epoll。

模拟举例:

  1. select/poll

老李去火车站买票,委托黄牛,然后每隔6小时电话黄牛询问,黄牛三天内买到票,然后老李去火车站交钱领票。 耗费:打电话

  1. epoll

老李去火车站买票,委托黄牛,黄牛买到后即通知老李去领,然后老李去火车站交钱领票。 耗费:无需打电话

​

# 信号驱动IO模型

I/O

信号驱动式IO就是指进程预先告知内核、向内核注册一个信号处理函数、然后用户进程返回不阻塞、当内核数据就绪时会发送一个信号给进程、用户进程便在信号处理函数中调用IO读取数据、从图中明白实际IO内核拷贝到用户进程的过程还是阻塞的、信号驱动式IO并没有实现真正的异步、因为通知到进程之后、依然是由进程来完成IO操作。

模拟举例:

老李去火车站买票,给售票员留下电话,有票后,售票员电话通知老李,然后老李去火车站交钱领票。 耗费:无需打电话

# 异步IO模型

I/O

当应用程序调用aio_read时,内核一方面去取数据报内容返回,另一方面将程序控制权还给应用进程,应用进程继续处理其他事情,是一种非阻塞的状态。

当内核中有数据报就绪时,由内核将数据报拷贝到应用程序中,返回aio_read中定义好的函数处理程序。

模拟举例:

老李去火车站买票,给售票员留下电话,有票后,售票员电话通知老李并快递送票上门。 耗费:无需打电话

#计算机网络
上次更新: 2022/12/01, 11:09:34
磁盘IO与swap分区
DDOS攻击下多IP防御思路

← 磁盘IO与swap分区 DDOS攻击下多IP防御思路→

最近更新
01
常用游戏反外挂技术总结
11-27
02
Golang开发实践万字总结
11-11
03
Redis万字总结
10-30
更多文章>
Theme by Vdoing | Copyright © 2011-2022 Ravior | 粤ICP备17060229号-3 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式