Open dushaoshuai opened 1 year ago
线程的栈大小固定,这个固定的栈既太大,又太小。
goroutine 的栈大小可动态变化^1。
线程由操作系统内核进行调度,切换线程时需要上下文切换,也就是将当前线程的状态保存在内存中,恢复下一个要执行的线程的状态,并且更新调度器的数据。因为线程有着不小的固定大小的栈,因此线程切换时会消耗较多的内存。
goroutine 由 Go 运行时调度器进行调度。Go 调度器将多(m)个 goroutine 调度运行在多(n)个线程上,即 m:n 调度。Go 调度器通过使用与 CPU 数量相等(默认行为,可调整^2)的线程减少线程频繁切换的内存开销。在 goroutine 间切换时也不需要内核上下文切换,开销更低。goroutine 要轻量很多。
线程切换由时钟中断触发,goroutine 切换由 Go 语言的一些机制触发。
线程有唯一标识,也就是线程 ID。
goroutine 没有唯一标识^3。
栈大小
线程的栈大小固定,这个固定的栈既太大,又太小。
goroutine 的栈大小可动态变化^1。
调度
调度开销
线程由操作系统内核进行调度,切换线程时需要上下文切换,也就是将当前线程的状态保存在内存中,恢复下一个要执行的线程的状态,并且更新调度器的数据。因为线程有着不小的固定大小的栈,因此线程切换时会消耗较多的内存。
goroutine 由 Go 运行时调度器进行调度。Go 调度器将多(m)个 goroutine 调度运行在多(n)个线程上,即 m:n 调度。Go 调度器通过使用与 CPU 数量相等(默认行为,可调整^2)的线程减少线程频繁切换的内存开销。在 goroutine 间切换时也不需要内核上下文切换,开销更低。goroutine 要轻量很多。
调度触发
线程切换由时钟中断触发,goroutine 切换由 Go 语言的一些机制触发。
身份标识
线程有唯一标识,也就是线程 ID。
goroutine 没有唯一标识^3。
参见