MST

星途 面试题库

面试题:Go语言中goroutine与线程的区别

请阐述Go语言里goroutine和传统线程在资源开销、调度方式、创建数量限制等方面有哪些主要区别。
49.4万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

资源开销

  • goroutine
    • 栈空间:初始栈空间很小,一般为2KB左右,随着需求动态增长和收缩,非常节省内存。例如一个简单的HTTP服务器,创建大量goroutine处理请求,因栈空间小,内存占用少。
    • 其他开销:创建和销毁的开销极小,不需要像传统线程那样进行复杂的内核态与用户态切换等操作。
  • 传统线程
    • 栈空间:栈空间一般固定且较大,通常为几MB,创建大量线程时会消耗大量内存。如一个多线程程序创建1000个线程,每个线程栈空间4MB,仅栈空间就消耗4GB内存。
    • 其他开销:创建、销毁和上下文切换开销较大,涉及操作系统内核调度,需要进行用户态到内核态的切换等复杂操作。

调度方式

  • goroutine
    • 由Go运行时(runtime)的调度器(GPM模型:G代表goroutine,P代表处理器,M代表操作系统线程)进行调度,属于协作式调度(又称非抢占式调度)。即一个goroutine在执行过程中主动让出CPU,如执行系统调用、I/O操作、调用runtime.Gosched()函数等。
    • 调度在用户态进行,不涉及操作系统内核,调度速度快,上下文切换开销小。
  • 传统线程
    • 由操作系统内核调度,采用抢占式调度,操作系统根据线程的优先级、时间片等因素强制剥夺线程的CPU使用权。
    • 上下文切换需要进入内核态,开销大,速度相对较慢。

创建数量限制

  • goroutine
    • 由于资源开销小,理论上可创建数量非常多,轻松创建数以万计甚至更多。例如在一个网络爬虫程序中,可以创建几万甚至几十万的goroutine并发请求网页。
  • 传统线程
    • 受系统资源(主要是内存,因每个线程栈空间大)限制,创建数量有限,一般在几千个左右。如果创建过多,可能导致系统内存耗尽,程序崩溃。