直接回答:线程由操作系统内核调度,是抢占式的:内核时钟中断可随时剥夺其 CPU;协程由用户态程序(语言运行时或框架)自行调度,是协作式的:只有在协程主动让出(yield/await)时才切换。协程切换不进出内核,只保存少量寄存器和栈信息,开销远低于线程。
展开解析:线程有独立的系统栈(通常 MB 级),数量受限;协程栈可动态增长,初始仅 KB 级,单机可轻松支撑十万级并发(如 Go 的 goroutine)。但协程的软肋是:一个协程若执行阻塞式系统调用(如同步文件 IO)或长时间计算不让出,会卡住整个调度线程,所以协程框架必须配合非阻塞 IO 或多线程调度器(如 Go 的 GMP 模型把 goroutine 复用到少量 OS 线程上)。追问方向:有栈协程与无栈协程(async/await 状态机)的区别、抢占式调度能否用于协程(Go 1.14 引入基于信号的抢占)。