异步 同步 阻塞 非阻塞

异步同步阻塞非阻塞

并发:同一时刻,单cpu只执行一个任务

并行:多CPU同时执行不同任务

同步和异步对结果而言:

同步:上一个任务必须执行完,下一步才能执行
异步:下一步的操作不需要等待上一步的完成

同步和异步

同步和异步是针对应用程序和内核的交互而言的,同步指的是用户进程触发IO 操作并等待或者轮询的去查看IO 操作是否就绪

而异步是指用户进程触发IO 操作以后便开始做自己的事情,而当IO 操作已经完成的时候会得到IO 完成的通知。

阻塞和非阻塞

阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方式,说白了是一种读取或者写入操作方法的实现方式,

阻塞方式下读取或者写入函数将一直等待,

而非阻塞方式下,读取或者写入方法会立即返回一个状态值。

调用者同步异步是针对来说的:

调用者发起一个请求后,一直干等被调用者的反馈就是同步,不必等去做别的事就是异步。

阻塞非阻塞是针对被调用者来说的

被调用者收到一个请求后,做完请求任务后才给出反馈就是阻塞,收到请求直接给出反馈再去做任务就是非阻塞。

我认为同步、异步、阻塞、非阻塞,是分3个层次的:CPU层次;线程层次;程序员感知层次。

CPU层次
或者说操作系统进行IO和任务调度的层次,现代操作系统通常使用异步非阻塞方式进行IO(有少部分IO可能会使用同步非阻塞轮询),

即发出IO请求之后,并不等待IO操作完成,而是继续执行下面的指令(非阻塞),

IO操作和CPU指令互不干扰(异步),最后通过中断的方式来通知IO操作完成结果。

线程层次/操作系统调度单元的层次

将底层的异步非阻塞的IO方式进行封装,如read,write以同步的方式展现出来。

同步阻塞的IO:线程没有资源时挂起并不执行,
同步非阻塞的IO:线程会消耗CPU资源在轮询上。

为了解决这一问题,就有3种思路:
多线程(同步阻塞);

IO多路复用(select,poll,epoll)(同步非阻塞,把阻塞点改变了位置)

直接暴露出异步的IO接口,如kernel-aio和IOCP(异步非阻塞)

程序员感知层次

直接使用select之类的接口比较复杂,IO多路复用进行封装的库和框架提供的API,又可以选择是以同步的方式或异步的方式来展现。

如python的asyncio库中,就通过协程,提供了同步阻塞式的API;

如node.js中,就通过回调函数,提供了异步非阻塞式的API。

总结比如node.js,我们可以说她在程序员感知层次提供了异步非阻塞的API,

也可以说在Linux下,她在线程层次以同步非阻塞的epoll来实现。

epoll和IOCP的区别:

epoll用于Linux系统,IOCP用于Windows系统;

epoll是同步非阻塞模型:当事件资源满足时发出可处理通知消息(主线程需要自己去处理);

IOCP是异步非阻塞模型,当事件完成时发出通知消息(工作线程帮主线程处理完了)。

yield return

python2 中 代码块同时有yield return,return后不能带结果,需要把结果封装成异常 ,用 raise 来返回

实现异步方法

  1. 定义两个函数,一个函数中把结果回调给另一个函数处理
  2. 同步写法编写异步,用异步装饰器,只需一个定义函数,用 yeild 唤醒处理
posted @ 2020-05-31 22:58  justblue  阅读(201)  评论(0编辑  收藏  举报