# 进程、线程、协程的区别
### 关系
![](https://img.kancloud.cn/bc/b1/bcb155964abee12726c52719877382af_754x645.png)
<center>图:1.5-1</center>
为了更简单的理解它们之间的关系,我们依然举个“栗子”帮助大家理解进程、线程、协程。
原型|比喻
-|-|
CPU|工厂
进程|车间
线程|生产线
协程|工人
一个工厂里面会有多个车间,每个车间有自己独立的物料、电力供应,这就好比是进程,有自己的独立内存地址和数据栈,开一个车间的成本非常高,我们需要有足够的大小的厂房。在工厂物料和电力都有限的情况下,一个车间开工其他车间就要停下来,这就类似上下文切换,所以这个切换是很浪费时间的。
一个车间场地允许的话可以直接多开几条生产线,这样成本就会比开一间车间要低得多,当我们一条生产线不够用的时候可以多开几条生产线,就好比我们在程序开线程一样防止一条生产线中工作不过来堵在那里。
生产线上的每一个工人都在协助完成一个产品的生成组装,前一个人把一个零件处理好了,然后交由下一个人进行处理。如果有一个人处理不过来,很多零件都堆积在某一个人那的时候,流水线后面的工人等不到上一个零件过来就没有办法继续返货,比如我们遇到了IO阻塞;当然狠心的老板不会让后面的工人闲下来,老板就让后面的工人去做别的事情,反正就是不让你偷懒。
### 上下文切换对比
- |进程|线程|协程
-|-|-|-|
切换者|操作系统|操作系统|开发者
切换时机|操作系统策略|操作系统策略|开发者程序指定
上下文|页全局目录、内核栈、硬件上下文|内核栈、硬件上下文|硬件上下文
切换内容保存|内存栈|内存栈|保存到用户的变量(用户栈或者用户堆)
切换过程|用户态->内核态->用户态|用户态->内核态->用户态|纯用户态
切换效率|低|中|高
切换开销|高|中|低
- 第一章:基础知识
- 课程简介
- PHP-FPM过渡常驻内存
- 进程
- 实战:实现Master-Worker
- 线程
- 实战:CC攻击器
- 协程
- 实战:实现waitGroup功能
- 进程、线程、协程的区别
- 第二章:初识Swoft2.0
- Swoft介绍
- Swoft环境安装
- gcc升级
- 安装Swoft框架
- 目录结构介绍
- SwoftCli工具
- Swoft配置
- 第三章:Swoft2.0核心
- 上下文
- 常驻内存没有上下文隔离
- 实战:手写swoole框架上下文管理
- Bean容器
- 实战:根据容器原理实现容器
- 实战:通过容器实现依赖注入
- Bean容器定义与使用
- 配置文件定义Bean
- 容器类型
- 面向接口的容器
- 注解
- 实战:实现注解
- 自定义Swoft注解类
- 事件
- 连接池
- 实战:Swoole实现连接池
- 第四章:Http服务器
- Http Server生命周期
- Http Server配置
- 控制器
- 路由
- 请求对象Request
- 响应对象Response
- Http异常处理
- 中间件
- 实战:中间件实现JWT登陆授权
- 第五章:验证器
- 内置验证类型
- 验证器的使用
- 自定义验证器
- 第六章:数据库操作
- 连接数据库
- 实体模型
- 模型事件
- 查询器
- 事务处理
- 连接池配置
- 读写分离
- 多数据库切换
- Models分层结构
- 实战:实现用户CURD API
- 第七章:Redis
- 连接redis和使用
- Redis连接池
- Redis集群配置(单机版)
- Redis集群配置(多服务器)
- Redis连接集群
- Redis实战:实现延时任务
- 第八章:AOP编程
- AOP概念
- AOP实现原理
- 实战实现AOP:静态代理
- 实战实现AOP:动态代理
- 切面注解介绍
- PointExecution切面
- PointBean切面
- PointAnnotation切面
- 实战:使用AOP实现日志记录
- 第九章:任务处理
- 进程使用
- 进程池使用
- 实战:进程消费队列
- 实战:进程实现RabbitMQ延时队列
- 异步任务
- 协程任务
- 定时任务