进程、线程、协程

进程、线程、协程

进程

进程是计算机中的程序关于某数据集合上的一次运行活动
是系统进行资源分配和调度的基本单位
是操作系统结构的基础

进程的三态模型

多道程序系统中 进程在处理器上交替运行 状态不断变化

proccess1.png

运行

当一个进程在处理机上运行时 则该进程处于运行状态
  • 处于此状态的进程的数目小于等于处理器的数目
  • 对于单处理机系统 处于运行状态的进程只有一个
  • 在没有其他进程可以执行时(例如所有进程处于阻塞状态)自动执行系统的空闲进程

就绪

当一个进程获得了除处理机以外的一切所需资源 则该进程处于就绪状态

阻塞/等待/睡眠

一个进程正在等待某一事件发生(例如请求I/O但等待I/O完成)而暂时停止运行
即使分配处理机也无法运行 则该进程处于阻塞状态

进程的五态模型

对于一个实际的系统 进程的状态及其转换更为复杂

proccess2.png

新建态

进程刚刚被创建时没有被提交的状态
等待系统完成创建进程的所有必要信息

活跃就绪/静止就绪

活跃就绪 => 是指进程在主存且可被调度的状态

静止就绪(挂起就绪)=> 是指进程被对换到辅存时的就绪状态
是不能被直接调度的状态
只有当主存中没有活跃就绪态进程 或者是静止就绪态进程具有更高的优先级
系统将把挂起的就绪态进程调度回主存并转换为活跃就绪

运行

当一个进程在处理机上运行时 则该进程处于运行状态
  • 处于此状态的进程的数目小于等于处理器的数目
  • 对于单处理机系统 处于运行状态的进程只有一个
  • 在没有其他进程可以执行时(例如所有进程处于阻塞状态)自动执行系统的空闲进程

活跃阻塞/静止阻塞

活跃阻塞 => 是指进程已在主存 一旦等待的事件产生便进入活跃就绪态

静止阻塞 => 进程对换到辅存时的阻塞状态 一旦等待的事件产生便进入静止就绪态

终止态

进程已结束运行 回收除进程控制块之外的其他资源
且让其他进程从进程控制块中收集有关信息

线程

线程 又称轻量级进程
是程序执行流的最小单元 是进程中的一个实体
是被系统独立调度和分派CPU的基本单位
线程自身不拥有系统资源 只拥有运行必须的资源
可与同一进程的其他线程共享进程所拥有的全部资源
一个线程可以创建和撤销另一个线程
同一进程中的多个线程之间可以并发执行
每个程序都至少有一个线程 若程序只有一个线程 那就是程序本身
多线程即单个程序同时运行多个线程

线程的状态

就绪

线程具备运行的所有条件 等待处理机 逻辑上可执行

阻塞

线程在等待一个事件(如某个信号量) 逻辑上不可执行

运行

线程占据处理机正在运行   

协程

协程是一种用户态的轻量级线程
协程的调度完全由用户控制
协程拥有自己的寄存器上下文和栈

协程调度切换

协程调度切换时 将寄存器上下文和栈保存到其他地方
切换回来时 恢复先前保存的寄存器上下文和栈
直接操作栈则基本没有内核切换的开销 可以不加锁的访问全局变量
所以上下文的切换非常块

线程与进程的区别

  • 线程是进程内的一个执行单元 进程内至少有一个线程 它们共享进程的地址空间 而进程有自己独立的地址空间
  • 进程是资源分配和拥有的单位 同一个进程内的线程共享进程的资源
  • 线程是处理器调度的基本单位 进程不是
  • 二者均可并发执行
  • 每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口 线程不能独立执行 必须依存在应用程序中 由应用程序提供多个线程执行控制

线程与协程的区别

  • 一个线程可以多个协程 一个进程也可以单独拥有多个协程
  • 线程进程都是同步机制 协程是异步机制
  • 协程能保留上一次调用时的状态 每次过程重入时 相对于进入上一次调用的状态

多进程

同一时间里 同一个计算机系统
允许两个或两个以上的进程处于运行状态
缺点 =>

- 多开进程意味多分配资源
- 进程间通讯不方便

多线程

线程就是把一个进程分为很多片 每一片可以是一个独立的流程
与多进程的区别是只会使用一个进程的资源
线程间可以直接通讯

同步阻塞

通过多进程 多线程来解决并发I/O的问题
一个请求创建一个进程 然后子进程进入循环同步阻塞地与客户端连接进行交互
收发并处理数据

实现

  • 创建一个socket
  • 进入while循环 阻塞在进程accept操作上 等待客户端连接进入
  • 主进程在多进程模型下通过fork创建子进程
  • 子进程/线程创建成功后进入while循环 阻塞在recv调用上 等待客户端向服务器发送数据
  • 收到数据后处理完毕使用send向客户端返回响应
  • 当客户端连接关闭时 子进程/线程退出并销毁所有资源 主进程/线程会回收掉此子进程/线程
缺点 =>

- 严重依赖进程数量
- 启动大量进程会带来额外的进程调度消耗

异步非阻塞

现在各种高并发异步I/O的服务器程序都是基于 epoll 实现的
I/O复用异步非阻塞程序使用经典的 Reactor 模型
本身不处理任何数据收发 只可以监视一个socket句柄的事件变化

实现/Reactor核心操作

  • add => 添加socket监听到Reactor
  • set => 修改事件监听 可以设置监听类型 (如可读、可写)
  • del => 从Reactor中移除 不再监听事件
  • callback => 事件发生后对应的处理逻辑 一般在add/set时指定制定

例子

Nginx => 多线程Reactor
Swoole => 多线程Reactor + 多进程Worker

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×