若转载教程,请注明出自SW-X框架官方文档
在Swoole中,协程的英文单词为:Coroutine
从Swoole4.0+开始,支持协程操作。

1、什么是协程

Swoole中的协程概念如下:

  1. 开发者可以无感知的用同步的代码编写方式达到异步 IO 的效果和性能,避免了传统异步回调所带来的离散的代码逻辑和陷入多层回调中导致代码无法维护
  2. 同时由于底层封装了协程,所以对比传统的 PHP 层协程框架,开发者不需要使用 yield 关键词来标识一个协程 IO 操作,所以不再需要对 yield 的语义进行深入理解以及对每一级的调用都修改为 yield,这极大的提高了开发效率
  3. 提供了各种类型完善的协程客户端,可以满足大部分开发者的需求。

协程可以简单理解为线程,只不过这个线程是用户态的,不需要操作系统参与,创建销毁和切换的成本非常低,和线程不同的是协程没法利用多核 cpu 的,想利用多核 cpu 需要依赖 Swoole 的多进程模型。
相对于进程或者线程,协程所有的操作都可以在用户态完成,创建和切换的消耗更低。
Swoole还提供了异步任务处理的功能,可以投递一个异步任务到TaskWorker进程池中执行,不影响当前请求的处理速度。
也就是想在协程中异步执行任务,也可以将某段代码异步执行。

2、协程的适用场景

协程非常适合并发编程,常见的并发编程场景如下:

  1. 高并发服务,如秒杀系统、高性能 API 接口、RPC 服务器,使用协程模式,服务的容错率会大大增加,某些接口出现故障时,不会导致整个服务崩溃;
  2. 爬虫,可实现非常强大的并发能力,即使是非常慢速的网络环境,也可以高效地利用带宽;
  3. 即时通信服务,如 IM 聊天、游戏服务器、物联网、消息服务器等等,可以确保消息通信完全无阻塞,每个消息包均可即时地被处理。

3、协程引入的问题

协程再为我们带来便利的同时,也引入了一些新的问题:

  1. 协程需要为每个并发保存栈内存并维护对应的虚拟机状态,如果程序并发很大可能会占用大量内存;
  2. 协程调度会增加额外的一些 CPU 开销。

尽管如此,在处理高并发应用时,使用协程带来的优势还是远远高于 PHP 默认的同步阻塞机制。

4、协程 vs 线程

Swoole 的协程在底层实现上是单线程的,因此同一时间只有一个协程在工作,协程的执行是串行的,这与线程不同,多个线程会被操作系统调度到多个 CPU 并行执行。
一个协程正在运行时,其他协程会停止工作。当前协程执行阻塞 IO 操作时会挂起,底层调度器会进入事件循环。当有 IO 完成事件时,底层调度器恢复事件对应的协程的执行。
在 Swoole 中对 CPU 多核的利用,仍然依赖于 Swoole 引擎的多进程机制。

5、什么是协程容器

上面我们已经说过,在Swoole中,首先每个协程可以简单的理解为一个线程,大家知道多线程是为了提高程序的并发,同样的多协程也是为了提高并发。
用户的每个请求都会创建一个协程,请求结束后协程结束,如果同时有成千上万的并发请求,某一时刻某个进程内部会存在成千上万的协程,那么 CPU 资源是有限的,到底执行哪个协程的代码?
协程容器则是为了决定到底让 CPU 执行哪个协程的代码决断过程就是协程调度。
Swoole中所有的协程必须在协程容器里面创建,Swoole 程序启动的时候大部分情况会自动创建一个协程容器。