why:
“同步-异步-阻塞-非阻塞”这四个名词都很熟悉,但是每次又说不清它们之间具体的区别。本次特意深入、全面的理解一下。
demo:
以老张烧水为例。
1、老张用普通的水壶烧水,同时自己在火炉旁等待水开 —— 同步阻塞式;
2、老张用普通的水壶烧上水后,去看电视,没看一会就去看一下水开了没有 —— 同步非阻塞;
3、老张用响壶烧水,同时自己在火炉旁等待水开 —— 异步阻塞式;
4、老张用响壶烧水,然后去看电视,等水壶响后去取热水 —— 异步非阻塞;
总结:“异步/同步”主要关注的是:两个物之间的信息交换机制。即老张和水壶之间的信息同步机制;
“阻塞/非阻塞”主要关注的是:一个人/事务处理中的状态。即老张烧水时的状态;
what:
“同步-异步”描述的是消息通信的机制。异步最典型的特点:需要callback、状态或者通知的方式来告知调用方结果。
“阻塞-非阻塞”描述的是程序在等待调用结果(消息,返回值)时的状态。最典型的特点:请求方,请求后,是否会被挂起,即什么事也不做的等待结果(调用方线程是否会被挂起block住)。
where(场景):
1、同步阻塞:
同步:sender发出req后,一直等到receiver有结果了才返回;
阻塞:sender发出请求后,一直被blocked,不能做任何其他事情;
2、异步阻塞:
异步:sender发出req后,立刻返回,然后等待receiver的callback,最后才读取res;
阻塞:sender等待callback期间一直处于block状态,不能做任何事情;
3、同步非阻塞:
同步:sender发出req后,立刻获得res,但是不是希望的结果;然后sender不停的主动轮询receiver,直到获得结果。整个过程是同步的;
非阻塞:sender在获得receiver结果期间,一直都是活跃的,可以做其他事情;
4、异步非阻塞:
异步:sender请求发送出去以后,立刻返回,然后再等待Receiver的callback,最后再次请求获取response,这整个过程是异步;
非阻塞:Sender等待Receiver的callback期间一直是可以处理其它事情的
I/O模型:
1、阻塞IO模型:
从调用者来看,属于:同步阻塞式
2、非阻塞式IO模型:
从调用者来看,属于:同步非阻塞式
3、IO多路复用:
从调用者来看,属于:同步阻塞式
4、信号驱动IO:
从调用者来看,属于:异步非阻塞
5、异步IO:告知内核启动某个操作,并让内核在整个操作完成后通知
从调用者来看,属于:异步非阻塞
IO总结:IO分两阶段,分别是:数据准备阶段和内核空间复制数据到用户空间
从而:
阻塞IO和非阻塞IO的区别在于:两阶段是否会被阻塞;
同步IO和异步IO的区别就在于:两阶段是否异步;
即:阻塞IO模型、非阻塞IO模型、IO复用模型(select/poll/epoll)、信号驱动IO模型都属于同步IO,因为阶段2都是同步阻塞的(尽管时间很短);异步IO的两阶段全交给操作系统了。