协程, Coroutine
协程, Coroutine 协程别名: 微线程,纤程。英文:Coroutine, Green threads, fibers 传统编程语言中子程序或者函数是层级调用的,函数可以调用其它函数, 调用者需要等待被调用者结束之后继续执行, 函数调用是通过栈实现的. 一个线程就是按顺序执行一个或几个子函数, 函数调用只有一个入口和一个出口. 协程看上去也是函数,但是执行过程中在子程序内部可以中断,然后执行别的函数, 然后再被调度回来执行. 协程比线程有更高的执行效率, 协程没有线程切换的开销 协程在用户空间调度, 不涉及系统调用或任何阻塞调用, 不需要用来守卫关键区块的同步性原语(primitive)比如互斥锁、信号量等,并且不需要来自操作系统的支持 协程不需要多线程的锁机制, 为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。 协程是协作式多任务的, 线程典型是抢占式多任务的 因为协程是一个线程执行,那怎么利用多核CPU呢?最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。 使用抢占式调度的线程实现协程,但是会失去某些利益(特别是对硬性实时操作的适合性和相对廉价的相互之间切换)。 协程是语言层级的构造,可看作一种形式的控制流,而线程是系统层级的构造。 名词对照 coroutine、goroutine、virtual thread、轻量级线程、协程、虚拟线程、用户态线程、绿色线程——这些名词基本上在说同一类东西,只是来自不同语言和时代: 术语 说明 coroutine(协程) 最广义的概念,包括协作式(asyncio)和抢占式(goroutine)两类 goroutine Go 的实现,抢占式,属于协程的子集 virtual thread(虚拟线程) Java 21 的叫法,强调"就是线程,只是轻量" green thread(绿色线程) 早期术语,泛指用户态管理的线程 用户态线程 / 轻量级线程 描述实现机制的技术术语 命名不同有历史原因: Go 作者刻意不叫"协程",因为传统协程是协作式的,而 goroutine 是运行时抢占式调度的,更像轻量级线程 Java 叫"虚拟线程"是为了向后兼容——复用 Thread API,让现有代码改动最小 严格说,asyncio 协程(协作式、无栈)和 goroutine / 虚拟线程(抢占式、有栈)不是一回事,但常被混称为"协程"。 为什么需要用户态线程 OS 线程太重了 一个 OS 线程的代价: 默认栈大小 1~8 MB(Linux 默认 8MB) 创建/销毁需要系统调用,耗时微秒级 上下文切换需要陷入内核,保存/恢复大量寄存器 线程数受 OS 限制,通常几千到几万个 典型场景:一个 HTTP 服务,每个请求一个线程,1 万并发连接 → 80GB 内存光用在栈上,还没开始干活。 ...