解锁 Go 并发超能力:Tutorials 用 5 个实战示例讲透 Goroutine、Channel 与 Select
2026/8/22 15:02:38 网站建设 项目流程

解锁 Go 并发超能力:Tutorials 用 5 个实战示例讲透 Goroutine、Channel 与 Select

【免费下载链接】tutorialsSource code from Jake Wright's YouTube tutorials项目地址: https://gitcode.com/gh_mirrors/tutorials5/tutorials

🚀 Tutorials 是 Jake Wright YouTube 编程教程的配套源码仓库,其中go/02-go-concurrency目录用5 个由浅入深的 Go 并发实战示例,帮你快速掌握 Goroutine、Channel 与 Select 三大核心机制。无需大段理论,跟着 5 个小文件就能建立完整的 Go 并发编程心智模型,是初学者难得的轻量级 Go 并发教程。

📦 项目概览:Go 并发教程源码都藏在哪?

仓库中 Go 相关内容分为两大部分:

目录内容定位
go/01-learn-go变量、循环、函数、结构体、指针等 9 个基础示例并发学习的前置基础
go/02-go-concurrencyGoroutine、WaitGroup、Channel、Select、Worker 池 5 个并发示例本文主角

建议先扫一眼 01-learn-go/07-functions.go 感受一下 Go 函数风格,再进入并发章节。下面 5 个示例难度递增,每个只聚焦一个知识点。

示例 1:一个go关键字,开启你的第一个 Goroutine

源码文件:go/02-go-concurrency/01-goroutine.go

func main() { go count("sheep") // 异步执行 count("fish") // 主线程执行 }

核心就 3 行:在函数调用前加一个go,该函数就会在独立的 Goroutine 中并发运行。

💡关键认知

  • Goroutine 是 Go 的轻量级协程,创建成本极低,可以轻松创建成千上万个
  • 主函数main一旦退出,整个程序立即结束——其他 Goroutine 会被"就地正法"
  • 这个示例故意让count变成死循环:你会发现"数鱼"的主线程其实活不长

这一步帮你建立最朴素的心智模型:go前缀 = 并行执行

示例 2:用 WaitGroup 优雅等待并发任务

源码文件:go/02-go-concurrency/02-wait-group.go

var wg sync.WaitGroup wg.Add(1) go func() { count("sheep") wg.Done() }() wg.Wait()

解决示例 1 的"程序跑不完"问题,sync.WaitGroup是标准答案,核心就 3 个方法:

  1. Add(n):声明要等待 n 个任务
  2. Done():每个任务结束时调用,计数减一
  3. Wait():阻塞主线程,直到计数归零

📌 记住这个"Add → Done → Wait"三部曲,它在真实项目(如并发爬虫、批量下载)中无处不在,是 Go 并发入门必会的同步工具。

示例 3:Channel 让数据在 Goroutine 之间安全流动

源码文件:go/02-go-concurrency/03-channels.go

c := make(chan string, 50) // 带缓冲的通道 go count("sheep", c) for msg := range c { fmt.Println(msg) }

Go 并发哲学的名言是"不要通过共享内存来通信,而要通过通信来共享内存",Channel 就是这句话的载体:

  • c <- value向通道发送数据,<-c从通道接收数据
  • make(chan string, 50)创建带 50 容量的缓冲通道,发送方不会被立刻阻塞
  • range会持续接收,直到发送方close(c)关闭通道后自动退出

相比共享变量加锁,Channel 把"谁在什么时候改数据"的问题彻底交给了通道本身,代码更直观、更不易出竞态条件。

示例 4:Select 多路监听,像 switch 一样调度多个通道

源码文件:go/02-go-concurrency/04-select.go

select { case msg1 := <-c1: // 每 500ms 一条消息 fmt.Println(msg1) case msg2 := <-c2: // 每 2s 一条消息 fmt.Println(msg2) }

当程序需要同时监听多个 Channel 时,select登场。它的玩法和switch几乎一致:

  • 每个case对应一个通道操作
  • 哪个通道先有数据,就执行哪个分支(无数据时阻塞等待)
  • 天然适合做超时控制、事件合并、心跳检测等场景

这个示例里两个 Goroutine 以不同频率向c1c2发消息,主循环用select统一接收——一个极简的"事件循环"就完成了。

示例 5:终极实战——Worker 池并行计算斐波那契

源码文件:go/02-go-concurrency/05-fib.go

前面 4 个示例的积木,在这里拼成一个完整的生产者-消费者模型

go worker(jobs, results) // 启动 4 个 worker // ... for i := 0; i < 100; i++ { jobs <- i } close(jobs)

精妙之处有三个:

  1. 任务分发:100 个斐波那契计算任务丢进jobs通道,4 个 worker 自动"抢活干"
  2. 方向限定worker(jobs <-chan int, results chan<- int)用只读/只写通道声明接口,编译器帮你防止误用
  3. 结果回收:所有结果汇入results通道,主循环收满 100 个即结束

这就是生产环境中最经典的 Worker 池模式:任务队列 + 固定数量工作协程,简单、可控、易扩展。

✅ 学习路线与源码获取

🗺️ 推荐学习顺序(与目录编号一致):

01-goroutine.go → 02-wait-group.go → 03-channels.go → 04-select.go → 05-fib.go

每个文件都不超过 35 行,配合运行观察输出,1~2 小时即可通关全部 Go 并发示例。

想动手练习?克隆完整源码仓库:

git clone https://gitcode.com/gh_mirrors/tutorials5/tutorials

仓库里还有go/01-learn-go的 9 个基础篇、Docker 与 Home Automation 实战模块,全部代码短小精悍,是系统入门多种技术的优质练习场。掌握这 5 个并发示例后,你已具备阅读和编写生产级 Go 并发程序的核心能力 💪。

【免费下载链接】tutorialsSource code from Jake Wright's YouTube tutorials项目地址: https://gitcode.com/gh_mirrors/tutorials5/tutorials

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询