Golang 并发编程入门:Goroutine 简介与底子用法

[复制链接]
发表于 2026-1-8 14:46:28 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×

一、什么是 Goroutine?

Goroutine 是 Golang 中的一种轻量级线程,用于实现并发利用。与传统线程相比,Goroutine 的上风在于它具有更低的资源斲丧和更高的服从。每个 Goroutine 在运行时被 Go 的调理器(Scheduler)管理,而且它们共享内存空间。这使得在单个体系线程上运行成千上万个 Goroutine 成为大概。
1、Goroutine 的特点:


  • 轻量级:内存开销非常小,约莫只需 2KB。
  • 非抢占式调理:Goroutine 志愿让出 CPU,通过协作完成使命切换。
  • 并发与并行:Goroutine 提供并发模子,多个使命可以同时举行。
  • 壅闭模子简化开辟:制止了复杂的回调函数,使代码布局更加轻便。

二、怎样启动 Goroutine

要启动 Goroutine,我们只必要在函数调用前加上 go 关键字。此利用会将该函数在单独的 Goroutine 中异步实行,主步调不会期待它完成。
语法:

  1. go 函数名(参数)
复制代码
示例 1:根本的 Goroutine 用法

  1. package main
  2. import (
  3.     "fmt"
  4.     "time"
  5. )
  6. func printMessage() {
  7.     fmt.Println("Goroutine is running!")
  8. }
  9. func main() {
  10.     go printMessage() // 启动 Goroutine
  11.     time.Sleep(1 * time.Second) // 暂停主线程,确保 Goroutine 执行完
  12.     fmt.Println("Main function is done.
  13. ")
  14. }
复制代码
输出:
  1. Goroutine is running!  
  2. Main function is done.
复制代码
表明:


  • 主 Goroutine(即 main 函数)立即启动了一个子 Goroutine 来运行 printMessage 函数。
  • 假如没有 time.Sleep,主 Goroutine 大概会在子 Goroutine 还未实行时竣事,导致没有输出。

三、主 Goroutine 与子 Goroutine 的关系


  • 主 Goroutine:main 函数所在的 Goroutine,步调从这里开始运行。
  • 子 Goroutine:由主 Goroutine 或其他 Goroutine 创建的 Goroutine。
关键点:假如主 Goroutine 竣事,全部未完成的子 Goroutine 也会被欺压制止。
示例 2:主线程竣事导致子 Goroutine 制止

  1. package main
  2. import (
  3.     "fmt"
  4.     "time"
  5. )
  6. func main() {
  7.     go func() {
  8.         time.Sleep(2 * time.Second)
  9.         fmt.Println("This message may never appear.")
  10.     }()
  11.     fmt.Println("Main function is done.
  12. ")
  13.     // 主 Goroutine 立即结束,子 Goroutine 没有机会完成
  14. }
复制代码
输出:
  1. Main function is done.
复制代码
表明:


  • 主 Goroutine 竣事时,全部未完成的子 Goroutine 会立即制止,因此不会看到子 Goroutine 的输出。

四、Goroutine 的参数通报

在 Golang 中,Goroutine 支持通报参数,但必要留意是按值通报,而不是按引用。
示例 3:Goroutine 通报参数

  1. package main
  2. import (
  3.     "fmt"
  4. )
  5. func printNumber(num int) {
  6.     fmt.Println("Number:", num)
  7. }
  8. func main() {
  9.     for i := 1; i <= 3; i++ {
  10.         go printNumber(i) // 启动 Goroutine 传递参数
  11.     }
  12.     fmt.Scanln() // 等待用户输入,防止程序提前结束
  13. }
复制代码
输出(大概):
  1. Number: 1  
  2. Number: 2  
  3. Number: 3
复制代码

五、匿名函数中的变量捕捉题目

Goroutine 常与匿名函数一起利用,但要鉴戒变量捕捉题目。在循环中启动 Goroutine 时,匿名函数大概捕捉的不是当前迭代变量的值,而是循环竣事后的变量。
示例 4:错误的变量捕捉

  1. package main
  2. import (
  3.     "fmt"
  4.     "time"
  5. )
  6. func main() {
  7.     for i := 1; i <= 3; i++ {
  8.         go func() {
  9.             fmt.Println(i) // 捕获的可能是循环结束后的 i
  10.         }()
  11.     }
  12.     time.Sleep(1 * time.Second)
  13. }
复制代码
输出:
  1. 4  
  2. 4  
  3. 4
复制代码
修改后的代码:将变量作为参数通报

  1. go func(n int) {
  2.     fmt.Println(n)
  3. }(i)
复制代码

六、利用 WaitGroup 期待 Goroutine 完成

time.Sleep 不是期待 Goroutine 完成的最佳方式。Go 提供了 sync.WaitGroup 来管理多个 Goroutine 的同步。
示例 5:利用 WaitGroup

  1. package main
  2. import (
  3.     "fmt"
  4.     "sync"
  5. )
  6. func printMessage(msg string, wg *sync.WaitGroup) {
  7.     defer wg.Done() // Goroutine 完成时调用 Done()
  8.     fmt.Println(msg)
  9. }
  10. func main() {
  11.     var wg sync.WaitGroup
  12.     wg.Add(3) // 等待 3 个 Goroutine
  13.     go printMessage("Hello", &wg)
  14.     go printMessage("from", &wg)
  15.     go printMessage("Goroutine!", &wg)
  16.     wg.Wait() // 等待所有 Goroutine 完成
  17.     fmt.Println("All Goroutines are done.")
  18. }
复制代码
输出:
  1. Hello  
  2. from  
  3. Goroutine!  
  4. All Goroutines are done.
复制代码
表明:


  • wg.Add(n) 体现必要期待 n 个 Goroutine 完成。
  • 每个 Goroutine 竣事时调用 wg.Done()。
  • wg.Wait() 会壅闭主 Goroutine,直到全部使命完成。

七、Goroutine 的典范应用场景


  • I/O 并发:处置惩罚大量网络哀求,镌汰相应时间。
  • 配景使命:实行定时使命、日记记录等。
  • 并行盘算:分布盘算使命,进步步调性能。
  • 定时器与延时利用:如每隔一段时间实行某个利用。

八、留意事项与最佳实践


  • 制止死锁:当 Goroutine 期待相互时大概出现死锁,应鉴戒处置惩罚共享资源。
  • 公道利用 WaitGroup 和 Channel:确保 Goroutine 的同步与通讯。
  • 制止启动过多 Goroutine:固然 Goroutine 轻量,但过多的 Goroutine 也会占用体系资源。
  • 调试工具:利用 go tool trace 和 pprof 举行性能调优和调试。

九、小结

Goroutine 是 Golang 的强盛并发工具,其高效、易用的特点让它成为开辟者实现并发步调的首选。在这篇博客中,我们先容了 Goroutine 的底子用法、参数通报和同步机制,并演示了常见的应用场景和留意事项。

在下一篇博客中,我将具体先容 通道(Channel) 的利用,它是 Goroutine 之间举行通讯的重要工具。敬请期待!
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表