一、进程间通信的同步/异步, 阻塞/非阻塞
进程间通信是通过send()和receive()两种基本操作完成的。消息传递可能是阻塞的或非阻塞的,也被称为同步或异步的----《操作系统概念(第九版)》
可以总结为以下几种形式
- 阻塞式发送:发送方send()后被阻塞,直到接收方接收
- 非阻塞式发送:发送方send()后,立即可以其他操作
- 阻塞式接收:接收方receive()后一直阻塞,直到消息到达
- 非阻塞式接收:接收方receive()后,要么得到一个有效的结果,要么得到一个空值
也就是说,从进程间通信的角度来看,阻塞和同步(非阻塞和异步)是同义词,需要从发送方和接收方区分对待。
我们所说的“阻塞”是进程在发起一个系统调用后(recv),由于该系统调用不能立即完成,需要等待一段事件,于是内核将进程挂起为“等待”状态,以确保它不会被调度执行,占用CPU资源
二、IO系统调用的阻塞、非阻塞、同步、异步
阻塞和非阻塞描述的是进程的一个操作是否会使得进程转变为“等待”状态。
1.为什么会阻塞、非阻塞、同步、异步与IO关系起来呢?
- 阻塞是和系统调用联系在一起的,要让一个进程进入“等待”状态,要么是它主动调用wait()或sleep()等挂起自己的操作,要么就是它调用系统调用,而系统调用涉及到IO操作,不能立即完成,于是内核先将该进程设置为“等待”状态,调度其他进程运行,等到IO操作完成,内核再让该进程回到“准备”状态。
2. 阻塞IO
- 系统调用需要进程IO操作,但是此时数据还未准备好,导致进程进入“等待”状态,即阻塞
- 举例:recv()函数
#include <sys/types.h> #include <sys/socket.h> ssize_t recv(int sockfd, void *buf, size_t len, int flags);
- 如果sockfd没有数据时,进程会等待数据到达,再继续。
- 阻塞下,返回成功接收的数据长度,数据都写到buf中。
3. 非阻塞IO
- 系统调用需要进程IO操作,不管数据是否准备好,系统调用直接返回,继续执行程序。是一种非阻塞式行为。
- 举例:recv()函数
#include <sys/types.h> #include <sys/socket.h> ssize_t recv(int sockfd, void *buf, size_t len, int flags);
- 设置sockfd是O_NONBLOCK
- 返回-1,errno设置为EGAIN或EWOULDBLOCK。buf中可以是完成的结果,也可以是一个不完整的结果,还可以是一个空值。
- 上图最后一次read是阻塞的,因为他需要等待数据从内核态到用户态
4. 异步IO
-
POSIX规范,由操作系统完成IO操作,然后通知应用进程数据已经读写完成。
-
系统调用需要进程IO操作,不管数据是否准备好,系统调用直接返回,继续执行程序;等IO操作完成后(这是由操作系统完成),内核会通知进程(一般是回调函数)。是一种非阻塞式行为。
-
Linux是没有完备的异步IO处理方式,但是可以模拟出这样的效果
-
并发模式下的异步:程序执行依赖于事件驱动。
-
- 举例:epoll_wait
#include <sys/epoll.h> int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
- 在主线程中完成监听,子线程中进行读写处理。当主线程中epoll_wait阻塞时,就会执行子线程进行读写处理。
- IO多路复用的监听和读写操作不在同一个线程下进行。
-
5. 同步IO
阻塞IO和非阻塞IO都涉及到等待数据从内核态到用户态的过程,因此都是同步的
- 并发模式下的同步
- 举例:
- mysql建立连接时,服务器发出连接请求,需要等到mysql返回响应,请求和响应是在同一个流程中。
- redis的pipeline:服务器先把所有的连接请求发出去(在同一个包中),等待redis返回响应;redis统一处理所有连接请求,再返回。
- 举例:
6. 总结
- 非阻塞I/O 系统调用 recv()操作立即返回的是任何可以立即拿到的数据,可以是完整的结果,也可以是不完整的结果,还可以是一个空值。
- 异步I/O系统调用recv()结果必须是完整的,但是这个操作完成的通知可以延迟到将来的一个时间点。
- 同步IO系统调用 recv()后,没得到结果就不返回。
- 阻塞IO系统调用 recv()后,没得到结果就不返回。
- 非阻塞I/O 系统调用和异步I/O系统调用都是非阻塞式的,只是返回结果与处理IO的事件点不同。
参考文章:
https://www.zhihu.com/question/19732473/answer/241673170
https://zhuanlan.zhihu.com/p/368089289