● 什么是同步、什么是异步?什么是阻塞、什么非阻塞?
我自己的理解,大白话啊,同步和异步指的是函数调用完成任务的程度。
一个任务的完成,包括发起、执行和结果返回三个阶段。
同步(synchronize)调用涵盖了这三个阶段。调用结束之后,任务肯定是有结果的,无论成败。
异步(asynchronization)调用则是只参与了一个环节,那就是“任务发起”。调用结束之后,任务执行的结果是什么,异步调用是不关心的。那任务结果如何获取呢,一般就是通过注册的回调函数或者信号处理函数、或者是查询某个结构体来获得任务结果。
阻塞和非阻塞指的就是,任务执行阶段,遇到某个条件不满足,是等待还是直接返回。所谓条件不满足,可能是拿不到锁、或者发送缓冲区空间不足等等。等待条件满足,那就是阻塞;否则,直接返回,那就是非阻塞。
综上,同步异步、阻塞非阻塞讨论的并不是一个概念。“同步是不是就是阻塞”、“异步是不是一定非阻塞”这种问题是没有意义、没法回答的。一个同步的函数接口,可以是阻塞、也可以是非阻塞,参考send函数的两种模式。一个异步的函数接口,理论上函数执行过程中也可能发生某种阻塞(比如等一把锁)、也可能不阻塞(尝试获取不到锁就返回)。
● linux五种I/O模型
讨论这个得基于上面关于“同步异步、阻塞非阻塞”的问题的掌握。
完成一个I/O,需要经历两个阶段:I/O就绪、I/O任务完成。什么叫I/O就绪?我自己的通俗理解,有数据可读(Input),或者有缓冲区空闲可写(Output),这就是I/O就绪。
基于这两个阶段,结合同步异步、阻塞非阻塞,形成了五种I/O模型:
同步阻塞(send())、同步非阻塞(send(MSG_DONTWAIT ))、异步IO调用(aio_read/write/…)这三种,都是不管I/O对象,直接发起I/O请求。举例子:不管有没有输入事件,直接上来就read;不管I/O对象此时是否接受输出,直接上来就write。三种模式的区别就是,异步I/O是把I/O请求发出就了事,同步I/O则是涵盖了任务发起、执行和返回三个阶段。同步阻塞,是I/O未就绪或者其他某种条件不满足的情况下一直等待;同步非阻塞则是一旦发现I/O未就绪则返回。
另外两种,信号驱动I/O和I/O多路复用都是等待I/O对象就绪了才发起I/O请求,而这两种他们的区别在于信号驱动I/O(sigaction)通过注册的信号处理函数,异步地获得就绪事件通知;I/O多路复用则是通过同步调用(select/poll/epoll)获得就绪事件通知。
参考:
https://zhuanlan.zhihu.com/p/540293434
https://blog.csdn.net/zhizhengguan/article/details/120527307
标签:异步,调用,阻塞,任务,同步,Linux,就绪 From: https://www.cnblogs.com/ljm583/p/18284874