一文理解异步同步阻塞与费阻塞

preview
需积分: 0 2 下载量 164 浏览量 更新于2018-06-04 收藏 123KB DOCX 举报
同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)。所谓同步,就是在发出一个*调用*时,在没有得到结果之前,该*调用*就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由*调用者*主动等待这个*调用*的结果。而异步则是相反,*调用*在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在*调用*发出后,*被调用者*通过状态、通知来通知调用者,或通过回调函数处理这个调用。 ### 一文理解异步同步阻塞与非阻塞 #### 同步与异步 在探讨异步和同步的概念前,我们首先需要明确这两者的区别。同步与异步主要关注的是消息通信机制,即synchronous communication 和 asynchronous communication。 **同步(Synchronous)**: - **定义**: 在发出一个调用时,如果没有得到结果,该调用就不会返回。一旦调用返回,就得到了返回值。这意味着调用者需要主动等待调用的结果。 - **特点**: 调用者必须等待响应才能继续执行下一步操作。 - **示例**: 如果你打电话给书店询问是否有某本书,书店老板会在查找后告知你结果。在这期间,你需要等待他的回复才能继续做其他事情。 **异步(Asynchronous)**: - **定义**: 调用发出后立即返回,不会等待结果。调用者不会立刻获得结果,而是通过状态、通知或回调函数来处理调用的结果。 - **特点**: 调用者可以在等待结果的同时执行其他任务。 - **示例**: 仍然以打电话给书店为例,但这次老板会直接告诉你他会查一下并稍后给你回复。在此期间,你可以去做其他事情。 **异步编程模型示例**: Node.js 是一种典型的异步编程环境,其中大部分操作(如文件I/O、网络请求等)都是以异步方式进行的,这样可以提高应用程序的整体性能。 #### 阻塞与非阻塞 阻塞和非阻塞主要关注程序在等待调用结果时的状态。 **阻塞(Blocking)**: - **定义**: 调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果后才会返回。 - **特点**: 线程在等待结果的过程中无法执行其他任务。 - **示例**: 仍以前述的书店场景为例,如果你采用阻塞式调用,那么你会一直等待书店老板的回复,直到得知书是否有货。 **非阻塞(Non-blocking)**: - **定义**: 在不能立刻得到结果之前,该调用不会阻塞当前线程。 - **特点**: 线程在等待结果的过程中可以继续执行其他任务。 - **示例**: 在非阻塞式调用的情况下,即使书店老板没有立即回复,你也可以先去做其他事情,并定期检查是否有回复。 #### I/O模型 由于进程无法直接访问外部设备,因此需要调用内核来进行I/O操作。I/O操作通常包含两个阶段:等待数据准备好(如从磁盘读取数据),以及将数据从内核空间复制到用户空间。根据数据响应方式的不同,可以将I/O模型分为以下几种: **阻塞式I/O模型**: - **特点**: 进程挂起等待数据准备好,然后数据从内核缓冲区复制到用户进程的缓冲区。 - **示例**: 默认情况下,大多数套接字采用的就是这种模型。 **非阻塞式I/O**: - **特点**: 用户进程不会阻塞,而是一直在询问数据是否准备好。第二阶段(数据从内核缓冲区复制到用户进程空间)仍然是阻塞的。 - **缺点**: 效率较低,因为需要不断轮询。 **I/O多路复用** (select, poll, epoll): - **特点**: 可以同时监控多个I/O操作。这些方法允许一个线程响应多个请求。 - **示例**: select 和 poll 都是通过轮询的方式实现多路复用,而 epoll 基于事件通知,效率更高。 **信号驱动式I/O**: - **特点**: 第一阶段是非阻塞的,当数据准备就绪时,直接用信号的方式通知线程。 - **应用**: 使用较少。 **异步I/O**: - **特点**: 整个操作(包括数据从内核复制到用户空间)完成后才通知用户进程。 - **示例**: 例如,在Linux中,可以通过 `aio_read` 和 `aio_write` 函数实现异步I/O。 #### Nginx中的epoll, poll, select **select**, **poll**, 和 **epoll** 都属于I/O复用模型,用于同时监控多个文件描述符的状态。 - **select** 和 **poll**: - **共同点**: 都是通过轮询的方式来监控文件描述符的状态。 - **不同点**: select 有限制文件描述符的数量,而 poll 没有此限制。此外,poll 的性能通常优于 select,因为它不需要为每个文件描述符分配内核空间。 - **epoll**: - **优点**: 相较于 select 和 poll,epoll 通过回调函数的方式工作,效率更高。它能够高效地管理大量文件描述符,避免了不必要的轮询操作。 通过以上的解释和示例,我们可以更好地理解同步与异步、阻塞与非阻塞以及不同I/O模型之间的差异。这些概念对于软件开发特别是高性能服务器端开发非常重要。