Go运行时与Goroutine的创建、调度和销毁


1. Goroutine是轻量级线程

Goroutine是Go语言并发编程的核心概念之一,它是一种比操作系统线程更轻量的并发执行单元。以下是Goroutine作为“轻量级线程”的具体体现:

(1)资源占用少

  • 操作系统线程
    操作系统线程(如POSIX线程或Windows线程)通常需要分配较大的栈空间(默认几MB),并且线程的创建、切换和销毁会涉及较多的系统调用,开销较大。

  • Goroutine
    Goroutine的初始栈空间非常小(通常只有几KB),并且栈空间会根据需要动态增长和缩减。这种设计使得Goroutine的创建和销毁开销极低,可以轻松创建成千上万个Goroutine。

(2)创建和切换开销低

  • 操作系统线程
    线程的切换需要保存和恢复大量的上下文信息(如寄存器状态、栈指针等),并且需要切换到内核态,开销较大。

  • Goroutine
    Goroutine的切换完全由Go运行时在用户态完成,不需要切换到内核态。Go运行时会维护一个调度器(Scheduler),负责在多个Goroutine之间进行高效的上下文切换。这种切换的开销远低于操作系统线程。

(3)与线程的关系

  • Goroutine并不是直接映射到操作系统线程上的,而是由Go运行时管理的。Go运行时会将多个Goroutine调度到少量的操作系统线程上运行。这种设计使得Goroutine的并发能力更强,资源利用率更高。

2. Goroutine由Go运行时管理

Go语言的运行时(Runtime)是一个内置的库,负责管理Goroutine的创建、调度、销毁等操作。以下是Go运行时对Goroutine管理的具体机制:

(1)Goroutine的创建

  • 使用go关键字可以创建一个Goroutine。例如:

    go func() {
        fmt.Println("Hello from a goroutine!")
    }()
    

    这行代码会启动一个新的Goroutine来执行匿名函数。

  • Go运行时会为每个Goroutine分配初始栈空间,并将其加入到调度队列中。

(2)Goroutine的调度

  • Go运行时包含一个调度器(Scheduler),负责将Goroutine分配到操作系统线程上执行。调度器的核心任务是:

    • 在多个Goroutine之间进行公平的上下文切换。
    • 将Goroutine绑定到可用的操作系统线程上。
    • 在Goroutine阻塞时(如等待I/O或channel操作),将其从线程上解绑,并调度其他Goroutine运行。
  • Go的调度器采用了一种称为M:N调度模型的机制:

    • M:操作系统线程(Machine)。
    • N:Goroutine。
    • Go运行时会将大量的Goroutine(N)调度到少量的操作系统线程(M)上运行。这种模型既保证了并发性能,又减少了线程切换的开销。

(3)Goroutine的销毁

  • 当一个Goroutine的任务执行完毕后,Go运行时会自动回收其占用的资源(如栈空间)。
  • 如果Goroutine因为阻塞操作(如channel通信)而无法继续执行,Go运行时会将其挂起,直到条件满足后再重新调度。

(4)Goroutine的协作式调度

  • Go的调度器是协作式的,而不是抢占式的。这意味着Goroutine只有在主动让出CPU时(如调用runtime.Gosched()、进行I/O操作或channel通信时),才会发生上下文切换。
  • 从Go 1.14开始,Go运行时引入了抢占式调度的支持,可以在长时间运行的Goroutine中强制进行上下文切换,以避免某些Goroutine独占CPU。

3. Goroutine的优势

通过上述机制,Goroutine具有以下优势:

  • 高并发:可以轻松创建大量Goroutine,适用于高并发场景。
  • 低开销:创建和切换的开销远低于操作系统线程。
  • 简单易用:开发者无需关心底层线程管理,只需关注业务逻辑。
  • 高效调度:Go运行时的调度器能够充分利用多核CPU,提高程序的并发性能。

4. 总结

“Goroutine是Go语言中的轻量级线程,由Go运行时管理”这句话准确地概括了Goroutine的核心特性:

  • Goroutine是一种比操作系统线程更轻量的并发执行单元,资源占用少、创建和切换开销低。
  • Go运行时负责Goroutine的创建、调度和销毁,通过M:N调度模型将大量Goroutine映射到少量操作系统线程上运行。
posted @   guanyubo  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
历史上的今天:
2024-03-03 利用单例模式与阻塞队列实现异步的日志系统,记录服务器运行状态
点击右上角即可分享
微信分享提示