进程
状态
创建 就绪 运行 阻塞 阻塞挂起 就绪挂起 结束
程序阻塞时,会将程序所占用的物理内存,swap到硬盘上,此时进程进入了挂起状态
程序sleep也会导致挂起
进程控制块(PCB)
进程描述信息
进程标识符 用户标识符
进程控制和管理信息
进程当前状态 进程的优先级
资源分配清单
有关内存地址空间或虚拟地址空间的信息
所打开的文件的列表,所使用的的I/O设备信息
CPU相关信息
CPU中各个寄存器的值,当进程切换时,CPU的状态信息都会被保存在相应地PCB中,以便程序能从断点出继续执行
线程
线程控制块(TCP)
一个进程可以存在多个线程,线程之间共享进程的资源,除了维护自己所必需的栈以及寄存器。
协程
用户态线程,在用户态空间实现的线程,不是由内核管理的线程,是由用户态的线程库来完成线程的管理
CPU上下文切换
CPU的上下文即程序计数器以及寄存器,程序计数器用来存储CPU正在执行的指令位置
CPU在执行任务前,需要设置好寄存器以及程序计数器
CPU上下文切换就是把前一个任务的CPU上下文保存起来,然后加载新任务,更新上下文信息。
任务即进程、线程和中断。
进程上下文切换
进程的上下文切换不仅包含了虚拟内存、栈、全局变量等用户空间的资源,也包含了内核堆栈、寄存器等内核空间的资源
线程上下文切换
线程是进程当中的一条执行流程。
同一个进程内的多个线程可以共享代码段、数据段、打开的文件资源等,但每个线程各自都有一套独立的寄存器和栈,这样可以确保线程的控制流是相对独立的。
只需要切换线程的私有数据、寄存器等不共享的数据。
比较
进程是资源分配的单位,线程是CPU调度的单位
调度算法
先来先服务
最短作业有限
高响应比优先
时间片轮转
最高优先级
多级反馈队列
抢占式/非抢占式
进程间通信
- 管道
- 消息队列
- 共享内存(虚拟内存映射相同的物理地址)
- 信号量(P/V)
- 信号(kill)
- socket
同步与互斥
同步
并发进程/线程在一些关键点上可能需要互相等待与互通消息,这种制约的等待与互通信息称为进程/线程同步。如操作A应在操作B之前执行…
互斥
如操作A与操作B不能在同一时刻执行…
实现
锁:加锁/解锁
信号量:P/V操作
都可以实现互斥,信号量还可以实现同步
哲学家就餐问题
死锁
死锁的四个必要条件:
- 互斥
- 持有并等待
- 不可剥夺
- 环路
解决死锁就是破坏这一个或多个条件。
最基本的锁有两种:
- 互斥锁,抢锁失败后,线程释放CPU(阻塞,用户态陷入内核态)
- 自旋锁,抢锁失败后,线程忙等待,知道拿到锁
上下文切换需要时间成本,如果锁住的代码执行时间较短,应该使用自旋锁。
读写锁
乐观锁 悲观锁
上面所提到的锁都是悲观锁
乐观锁全称并没有加锁,也叫无锁编程(在线文档),虽然祛除了加锁解锁的操作,但是一旦发生冲突,重试的成本非常高,适合在冲突概率低,且加锁成本非常高的场景。