01. Goroutine 详解
Goroutine 是 Go 的轻量级线程,由 Go 运行时调度。
Goroutine 的特点:
- 初始栈只有几 KB,可动态增长
- 创建成本极低,可创建成千上万个
- 由 Go 运行时调度(M:N 调度模型)
- 同一进程内的 goroutine 共享内存
go
package main
import (
"fmt"
"runtime"
"sync"
"time"
)
func main() {
// 打印当前 GOMAXPROCS
fmt.Println("CPU 核心数:", runtime.GOMAXPROCS(0))
// 使用 WaitGroup 等待所有 goroutine
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Printf("Worker %d 完成\n", id)
}(i)
}
wg.Wait()
fmt.Println("所有 worker 完成")
}02. Channel 通信
Channel 是 goroutine 之间通信的管道,遵循 CSP(Communicating Sequential Processes)模型。
Channel 类型:
- 无缓冲 channel:同步通信
- 有缓冲 channel:异步通信
- 只读/只写 channel:限制方向
- 关闭 channel:通知接收方
go
package main
import (
"fmt"
"sync"
)
func main() {
// 无缓冲 channel
ch := make(chan string)
go func() {
ch <- "你好"
}()
msg := <-ch
fmt.Println(msg) // 你好
// 有缓冲 channel
buffered := make(chan int, 3)
buffered <- 1
buffered <- 2
buffered <- 3
fmt.Println(<-buffered) // 1
// 使用 WaitGroup 和 channel 实现 worker pool
var wg sync.WaitGroup
jobs := make(chan int, 10)
results := make(chan int, 10)
// 启动 3 个 worker
for w := 0; w < 3; w++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
for job := range jobs {
results <- job * 2
}
}(w)
}
// 发送任务
for j := 0; j < 5; j++ {
jobs <- j
}
close(jobs)
// 等待 worker 完成
go func() {
wg.Wait()
close(results)
}()
// 收集结果
for result := range results {
fmt.Println("结果:", result)
}
}03. Select 语句
Select 语句用于在多个 channel 操作中选择一个执行。
Select 的特点:
- 随机选择一个就绪的 case
- 如果没有就绪的 case,阻塞等待
- 支持 default case(非阻塞)
go
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
time.Sleep(1 * time.Second)
ch1 <- "来自 channel 1"
}()
go func() {
time.Sleep(2 * time.Second)
ch2 <- "来自 channel 2"
}()
// 使用 select 等待第一个就绪的 channel
select {
case msg := <-ch1:
fmt.Println(msg)
case msg := <-ch2:
fmt.Println(msg)
case <-time.After(3 * time.Second):
fmt.Println("超时")
}
// 非阻塞操作
messages := make(chan string)
select {
case msg := <-messages:
fmt.Println(msg)
default:
fmt.Println("没有消息")
}
}04. 并发模式
Go 提供多种并发模式处理复杂的并发场景。
常用模式:
- Fan-out/Fan-in:任务分发和结果聚合
- Pipeline:流水线处理
- Context:控制 goroutine 生命周期
go
package main
import (
"context"
"fmt"
"time"
)
// Context 控制
func worker(ctx context.Context, id int) {
for {
select {
case <-ctx.Done():
fmt.Printf("Worker %d 停止: %v\n", id, ctx.Err())
return
default:
fmt.Printf("Worker %d 工作中\n", id)
time.Sleep(500 * time.Millisecond)
}
}
}
func main() {
// Context 控制
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
for i := 0; i < 3; i++ {
go worker(ctx, i)
}
time.Sleep(4 * time.Second)
}知识测验
第 1/5 题正确 0
Goroutine 和操作系统线程的区别是什么?
下一节
下一节 错误处理