操作系统中线程是比进程更加轻量级的调度执行单位。
一个进程里面的线程可以共享资源(内存地址、文件IO) ,又可以独立调度。
内核线程 1:1
先介绍一下内核线程 , 内核线程就是直接由操作系统内核支持的线程。由内核完成线程切换,内核操纵调度器完成线程调度。 - KLT(Kernel-Level Thread)
但是程序一般不会直接使用内核线程 , 而是使用内核线程的高级接口 - 轻量级进程LWP(Lightweight Process) , 即一个语言里面常说的线程 , 运行在用户空间
但是因为和内核线程1:1 ,所以线程的操作都是需要内核支持完成 , 即需要在用户态和内核态来回切换 , 所以一个系统支持的LWP很少。
为什么用户态和内核态切换成本很高? 两个状态状态来回切换 ,需要响应中断、保护和恢复现场 JDK8 线程模型
用户线程 1:N
广义来说,只要一个线程不是内核线程,那么就是用户线程 UT - 最初都是协同调度多个用户线程 ,所以又被称之为协程 coroutiue
狭义的用户线程是建立在用户空间的线程库上的 ,系统内核感知不到 , 用户线程的建立、调度、同步都是在用户态完成
但是因为没有内核的支援,线程的各种操作都需要自己处理,因为操作系统只能把资源分配给处理器,所以实现都很复杂
近期的 Goroutine:
- 同时对于用户线程的调度而言,会做完整的栈的保护和恢复工作 , 所以又被称之为有栈协程
- 那么无栈协程如何完成现场保护呢? 那就是使用有限状态机,状态保存在闭包里面 , 所以比有栈协程还要轻量 - 如 await、async 关键字
有栈协程 & 无栈协程
用户线程 + 轻量级进程 N:M
既存在用户线程,也存在轻量级进程
因为用户线程在用户空间, 所以用户线程的创立、切换、结束等操作很轻量 同时因为存在轻量级进程作为桥梁 , 可以使用内核支持的线程调度和处理器映射的功能
- 复习一下操作系统的线程模型 (@2023-12-28)