❖ 异步IO Asynchronous I/O

"IO编程中,Stream(流)是一个很重要的概念,可以把流想象成一个水管,数据就是水管里的水,但是只能单向流动。Input Stream就是数据从外面(磁盘、网络)流进内存,Output Stream就是数据从内存流到外面去。" - 阮一峰

参考:异步IO - 阮一峰官网

编程时我们常面对的I/O有:

  • 磁盘I/O:就是我们常用的file.open("/path/to/file")等语句直接读取本地文件。
  • 网络I/O:就是socket.receive()socket.accpet()这样的与别的电脑沟通的语句。
  • 内存I/O:就是StringIO.write()STRINGIO.getvalue()等直接在内存里读写的语句。

内存的IO读写极快,远远远高于磁盘和网络的IO读取写入。比如要把100M的数据写入磁盘,CPU输出100M的数据只需要0.01秒,可是磁盘要接收这100M数据可能需要10秒。
如果不涉及IO读取写入,CPU执行代码速度是极快的,一旦碰上了需要读写的地方,就要停下来等着龟速的IO完成,再执行下一句。

这就造成了严重的拖累,这不合理。处理的事情少的时候还好说,一旦遇到高并发要求这是一个必须要解决的问题。

所以就出现了异步IO这个策略。

所有的IO都存在一样的共性:堵塞。
根据IO是否堵塞,分为了这两种:

  • 同步IO (Synchronous I/O):程序遇到IO读写时,要停下来等待其完成才执行下一句。
  • 异步IO (Asynchronous I/O):程序遇到IO读写时,不等待而直接执行下一句。

但是,如果没有接收到上一步IO的值,之后的代码都没法正常执行啊?
所以,正常的运行逻辑是不行的,必须改变代码逻辑才能使用异步IO
我们称这种逻辑为:异步IO模型

异步IO模型:Event Loop

同步IO模型,是线性的,从上到下,一通到底。
异步IO模型,是循环的,一直在做死循环,我们称之为消息循环 (Event Loop)。

典型异步IO模型的代码:

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

异步IO模型需要一个Event Loop,即主线程不断地重复读取消息->处理消息这一过程。
Event Loop其实早在应用在桌面应用程序中了。一个GUI程序的主线程就负责不停地读取消息并处理消息。所有的键盘、鼠标等消息都被发送到GUI程序的消息队列中,然后由GUI程序的主线程处理。

这种Event Loop,是一种什么样的逻辑呢?

记住,这种东西总是在处理高并发的问题,也就是同时发起很多很多个任务的问题。异步IO解决的就是这种尽快处理完任务的问题。

也就是说,先决条件是:
每个任务必须是平行平等的,才能利用到异步IO。如果任务之间有前后、上下的关系,那么必然也必须是线性的。只有做到平等,才能做到平行,即利用到循环。

记住这点,对理解异步IO很重要。一旦理解异步IO,就能很快的理解多进程、多线程、协程、异步socket等一系列常见话题。

猜你喜欢

转载自blog.csdn.net/weixin_33851429/article/details/87474617