浅谈异步IO

浅谈异步IO我们已经知道 CPU 的速度远远快于磁盘 网络等 IO 在一个线程中 CPU 执行代码的速度极快 然而 一旦遇到 IO 操作 如读写文件 发送网络数据时 就需要等待 IO 操作完成 才能继续进行下一步操作 这种情况称为同步 IO 在 IO 操作的过程中 当前线程被挂起 而其他需要 CPU 执行的代码就无法被当前线程执行了 因为一个 IO 操作就阻塞了当前线程 导致其他代码无法执行 所以我们必须使用多线程或者多

我们已经知道,CPU的速度远远快于磁盘、网络等IO。在一个线程中,CPU执行代码的速度极快,然而,一旦遇到IO操作,如读写文件、发送网络数据时,就需要等待IO操作完成,才能继续进行下一步操作。这种情况称为同步IO。

在IO操作的过程中,当前线程被挂起,而其他需要CPU执行的代码就无法被当前线程执行了。

因为一个IO操作就阻塞了当前线程,导致其他代码无法执行,所以我们必须使用多线程或者多进程来并发执行代码,为多个用户服务。每个用户都会分配一个线程,如果遇到IO导致线程被挂起,其他用户的线程不受影响。

多线程和多进程的模型虽然解决了并发问题,但是系统不能无上限地增加线程。由于系统切换线程的开销也很大,所以,一旦线程数量过多,CPU的时间就花在线程切换上了,真正运行代码的时间就少了,结果导致性能严重下降。

由于我们要解决的问题是CPU高速执行能力和IO设备的龟速严重不匹配,多线程和多进程只是解决这一问题的一种方法。

另一种解决IO问题的方法是异步IO。当代码需要执行一个耗时的IO操作时,它只发出IO指令,并不等待IO结果,然后就去执行其他代码了。一段时间后,当IO返回结果时,再通知CPU进行处理。

可以想象如果按普通顺序写出的代码实际上是没法完成异步IO的:

do_something() f = open('/path/to/file', 'r') r = f.read() # <==线程在此处停顿等待IO操作结果 # IO操作完成后线程才能继续执行 do_something_others() 

所以,同步IO模型的代码是无法实现异步IO模型的。

异步IO模型需要一个消息循环,在消息循环中,主线程不断地重复“读取消息-处理消息”这一过程

loop = get_event_loop() while True: event = loop.get_event() process_event(event) 

消息模型其实早在应用在桌面应用程序中了。一个GUI程序的主线程就负责不停地读取消息并处理消息。所有的键盘、鼠标等消息都被发送到GUI程序的消息队列中,然后由GUI程序的主线程处理。

由于GUI线程处理键盘、鼠标等消息的速度非常快,所以用户感觉不到延迟。某些时候,GUI线程在一个消息处理的过程中遇到问题导致一次消息处理时间过长,此时,用户会感觉到整个GUI程序停止响应了,敲键盘、点鼠标都没有反应。这种情况说明在消息模型中,处理一个消息必须非常迅速,否则,主线程将无法及时处理消息队列中的其他消息,导致程序看上去停止响应。

消息模型是如何解决同步IO必须等待IO操作这一问题的呢?当遇到IO操作时,代码只负责发出IO请求,不等待IO结果,然后直接结束本轮消息处理,进入下一轮消息处理过程。当IO操作完成后,将收到一条“IO完成”的消息,处理该消息时就可以直接获取IO操作结果。

在“发出IO请求”到收到“IO完成”的这段时间里,同步IO模型下,主线程只能挂起,但异步IO模型下,主线程并没有休息,而是在消息循环中继续处理其他消息。这样,在异步IO模型下,一个线程就可以同时处理多个IO请求,并且没有切换线程的操作。对于大多数IO密集型的应用程序,使用异步IO将大大提升系统的多任务处理能力。

注:本文仅供学习借鉴,转自https://www.liaoxuefeng.com/wiki/00264a6bfdf42a6d3a2e542c000/000facb23834c78c6c

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/226613.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午10:32
下一篇 2026年3月16日 下午10:32


相关推荐

  • js 保留小数点后两位。或小数点后为0的话 显示为整数

    num.toFixed(2)四舍五入varnum=2.446242342;num=num.toFixed(2);console.log(num);//2.45console.log(typeofnum);//string不四舍五入向下取整num=Math.floor(num*100)/100;console.log(num);//2…

    2022年4月7日
    189
  • typora图床阿里云_织梦七牛云

    typora图床阿里云_织梦七牛云一、创建并上传文件到存储空间1.注册七牛账号,并且实名认证2.创建储存空间打开侧边栏,选择对象存储选择新建空间存储空间名称:按规则随便取存储区域:选择离靠近的地区访问控制:选择公开,否则

    2022年8月16日
    10
  • Python基本语法

    Python基本语法Python基本语法

    2022年4月22日
    32
  • taiko脚本录制

    taiko脚本录制taiko 他是一个 web 自动化的测试软件 简单使用 安装 node js 打开 node 官网 https nodejs org en 下载 14 把版本稳定版下载安装完成后 win R 输入 cmd 打开命令窗口输入 node v 提示版本号就表示安装成功安装 taiko 直接输入命令 npminstall gtaiko 就开始下载了 下载完成后在直接 taiko v 查看是否安装成功显示版本就说明已经下载安装完成了开始记录测试 录制脚本 taiko 启动浏览器 默

    2026年3月18日
    2
  • matlab randint函数

    matlab randint函数randint n m 产生的是一个 n m 维的矩阵 矩阵的元素或者是 0 或者是 1 是随机的 如果想产生一个范围的数 可以设置一个区间 如 randint 2 3 16 就是产生一个 2 3 随机矩阵 这个矩阵的元素是区间 16 的随机数 randint 3 3 ans nbsp nbsp nbsp nbsp 1 nbsp nbsp nbsp nbsp 1 nbsp nbsp nbsp nbsp 0 nbsp nbsp nbsp nbsp 1 nbsp nbsp nbsp nbsp 1 nbsp nbsp nbsp nbsp 0 nbsp nbsp nbsp nbsp 0 nbsp nbsp nbsp

    2025年11月4日
    2
  • 遍历ArrayList的过程中移除元素的方式

    遍历ArrayList的过程中移除元素的方式错误方法一使用for循环正序遍历ArrayList,使用remove移除元素结果如下,只删除了一个“3”原因:在匹配到第一个要删除的元素并移除时,后面元素会往前移位,导致索引位置改变,从而漏掉后面一个元素。publicstaticvoidmain(String[]args){ ArrayList<String>list=newArrayList<>(); list.add(“1”); list.add(“2”); list.add(“3”

    2022年7月22日
    16

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号