diff --git a/notes/计算机操作系统 - 进程管理.md b/notes/计算机操作系统 - 进程管理.md index 36bc965b..d1cd357e 100644 --- a/notes/计算机操作系统 - 进程管理.md +++ b/notes/计算机操作系统 - 进程管理.md @@ -5,6 +5,7 @@ * [1. 进程](#1-进程) * [2. 线程](#2-线程) * [3. 区别](#3-区别) + * [4. 协程](#4-协程) * [进程状态的切换](#进程状态的切换) * [进程调度算法](#进程调度算法) * [1. 批处理系统](#1-批处理系统) @@ -68,6 +69,18 @@ QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 H 线程间可以通过直接读写同一进程中的数据进行通信,但是进程通信需要借助 IPC。 +### 4. 协程 + +协程(Coroutine)是在用户态实现的轻量级线程,由程序自己调度,而不是由操作系统内核调度。协程在等待 I/O 时主动让出执行权,运行时再把其它协程调度到同一个线程上执行。 + +与线程相比: + +- 切换在用户态完成,只需要保存少量寄存器,不需要陷入内核,开销小; +- 占用的内存少,可以同时存在大量协程,而每个线程都要预留独立的栈,例如 64 位 Linux 上 Java 线程的栈默认为 1 MB,线程数量有限; +- 同一个线程上的协程不能并行执行,要利用多核仍然需要多个线程;协程中如果执行了阻塞的系统调用,所在的线程会被阻塞,所以协程的运行时通常把 I/O 改为非阻塞的方式。 + +Java 21 正式引入的虚拟线程([JEP 444](https://openjdk.org/jeps/444))就是 JVM 实现的协程:虚拟线程由 JVM 调度到少量的平台线程上运行,执行阻塞 I/O 时从平台线程上卸载,让平台线程去执行其它虚拟线程。虚拟线程的创建成本很低,不需要用线程池复用,需要限制并发数时使用信号量。在 JDK 21 中,虚拟线程在 synchronized 块内阻塞时无法卸载,JDK 24 起([JEP 491](https://openjdk.org/jeps/491))基本消除了这个限制。 + ## 进程状态的切换