# 2.4 异步、并发

## 异步

### 应用程序及内核
Linux操作系统在设计上将虚拟空间划分为用户空间和内核空间，两者做了隔离是相互独立的，用户空间给应用程序使用，内核空间给内核使用。内核具有最高权限，可以访问受保护的内存空间，可以访问底层的硬件设备。而这些是应用程序所不具备的，但应用程序可以通过调用内核提供的接口来间接访问或操作。所谓的常见的IO模型就是基于应用程序和内核之间的交互所提出来的。以一次网络IO请求过程中的read操作为例，请求数据会先拷贝到系统内核的缓冲区（内核空间），再从操作系统的内核缓冲区拷贝到应用程序的地址空间（用户空间）。而从内核空间将数据拷贝到用户空间过程中，就会经历两个阶段：

* 等待数据准备
* 拷贝数据

也正因为有了这两个阶段，才提出了各种网络I/O模型。

### 同步和异步

同步和异步的概念描述的是应用程序与内核的交互方式，同步是指应用程序发起I/O请求后需要等待或者轮询内核I/O操作完成后才能继续执行；而异步是指应用程序发起I/O请求后仍继续执行，当内核I/O操作完成后会通知应用程序，或者调用应用程序注册的回调函数。

### 阻塞和非阻塞

阻塞和非阻塞的概念描述的是应用程序调用内核IO操作的方式，阻塞是指I/O操作需要彻底完成后才返回到用户空间；而非阻塞是指I/O操作被调用后立即返回给用户一个状态值，无需等到I/O操作彻底完成。

### 常见的网络IO模型

1. 同步阻塞IO（Blocking IO）

   进程发出IO请求后，进入阻塞状态，直到内核返回数据，才重新继续执行

2. 同步非阻塞IO（Non-blocking IO）

   进程发出IO请求后，不阻塞，如果数据没准备好，直接返回错误

3. IO多路复用（IO Multiplexing）

   IO复用阻塞在select、poll或epoll这样的系统调用上，通过这种方式在不使用多线程的前提下，单个进程可以同时处理多个网络连接的IO

4. 异步IO（Asynchronous IO）

   在一个进程发出IO请求后直接返回，内核在整个操作（包括数据复制都进程缓存区）完成后通知进程

## 并行

在操作系统中，一个时间段中有几个程序都处于已启动运行到运行完毕之间，且这几个程序都是在同一个处理机上运行，但任一个时刻点上只有一个程序在处理机上运行。

### 并发和并行的区别：

* 并发（concurrency）：逻辑上具备同时处理多个任务的能力
* 并行（parallesim）：物理上在同一时刻执行多个并发任务，依赖多核处理器等物理设备

### 并发编程模型

#### 多进程

  进程拥有自己独立的堆和栈，既不共享堆，亦不共享栈，进程由操作系统调度。多进程是在操作系统层面进行并发的基本模式。同时也是开销最大的模式。在Linux平台上很多工具链正是采用这种模式在工作。比如某个Web服务器，它会有专门的进程负责网络端口的监听和链接管理，还会有专门的进程负责事务和运算。这种方法的好处在于简单、进程间互不影响，坏处在于系统开销大,因为所有的进程都是由内核管理的。

#### 多线程

  线程拥有自己独立的栈和共享的堆，共享堆，不共享栈，线程亦由操作系统调度(标准线程是的)。多线程在大部分操作系统上都属于系统层面的并发模式，也是我们使用最多的最有效的一种模式。目前我们所见的几乎所有工具链都会使用这种模式。它比多进程的开销小很多，但是其开销依旧比较大，且在高并发模式下效率会有影响。

#### 基于回调的非阻塞/异步IO

  这种架构的诞生实际上来源于多线程模式的危机，在很多高并发服务器开发实践中，使用多线程模式会很快耗尽服务器的内存和CPU资源。而这种模式通过事件驱动的方式使用异步IO，使服务器持续运转，且尽可能地少用线程，降低开销，它目前在Node.js/PHP Swoole扩展中得到了很好的实践。但是使用这种模式，编程比多线程要复杂,因为它把流程做了分割，对于问题本身的反应不够自然。

#### 协程

  协程英文“coroutine”，协程和线程一样共享堆，不共享栈，协程由程序员在协程的代码里显示调度。协程和线程的区别是：协程避免了无意义的调度，由此可以提高性能，但也因此，程序员必须自己承担调度的责任，同时，协程也失去了标准线程使用多CPU的能力。协程本质上是一种用户态线程，不需要操作系统来进行抢占式调度，且在真正的实现中寄存于线程中。因此，系统开销极小，可以有效提高线程的任务并发性，而避免多线程的缺点。使用协程的优点是编程简单，结构清晰；缺点是需要语言的支持，如果不支持，则需要用户在程序中自行实现调度器。目前，原生支持协程的语言还很少。

# links
  * [目录](../README.md)
  * 上一节: [协程原理](2.3-协程原理.md)
  * 下一节: [小结](2.5-小结.md)