dushaoshuai / dushaoshuai.github.io

0 stars 0 forks source link

Go: goroutine 和线程的区别 #112

Open dushaoshuai opened 1 year ago

dushaoshuai commented 1 year ago

栈大小

线程的栈大小固定,这个固定的栈既太大,又太小。

goroutine 的栈大小可动态变化^1

调度

调度开销

线程由操作系统内核进行调度,切换线程时需要上下文切换,也就是将当前线程的状态保存在内存中,恢复下一个要执行的线程的状态,并且更新调度器的数据。因为线程有着不小的固定大小的栈,因此线程切换时会消耗较多的内存。

goroutine 由 Go 运行时调度器进行调度。Go 调度器将多(m)个 goroutine 调度运行在多(n)个线程上,即 m:n 调度。Go 调度器通过使用与 CPU 数量相等(默认行为,可调整^2)的线程减少线程频繁切换的内存开销。在 goroutine 间切换时也不需要内核上下文切换,开销更低。goroutine 要轻量很多。

调度触发

线程切换由时钟中断触发,goroutine 切换由 Go 语言的一些机制触发。

身份标识

线程有唯一标识,也就是线程 ID。

goroutine 没有唯一标识^3

参见