并发编程

并发编程是 Go 语言最强大的特性之一。Go 在语言层面提供了 Goroutine 和 Channel,让并发编程变得简单高效。本部分将系统讲解 Go 的并发模型和实践技巧。

章节内容

22. Goroutine 入门

Goroutine 是 Go 语言轻量级线程的实现。本章讲解:

  • Goroutine 的概念
  • Goroutine 的创建
  • Goroutine 的调度
  • Goroutine 与线程的区别
  • Goroutine 的生命周期

23. Channel 通道

Channel 是 Goroutine 之间通信的管道。本章涵盖:

  • Channel 的创建和使用
  • 无缓冲 vs 有缓冲 Channel
  • Channel 的关闭
  • 单向 Channel
  • Channel 的遍历

24. Select 语句

Select 用于处理多个 Channel 操作。本章介绍:

  • Select 语法
  • 超时处理
  • 非阻塞操作
  • Select 与 for 配合
  • 随机选择

25. 并发同步

并发同步用于协调多个 Goroutine 的执行。本章讲解:

  • sync.Mutex 互斥锁
  • sync.RWMutex 读写锁
  • sync.WaitGroup 等待组
  • sync.Once 单次执行
  • sync.Map 并发安全 Map

26. Context 包

Context 用于控制 Goroutine 的生命周期。本章涵盖:

  • Context 的概念
  • Context 的创建
  • Context 的传递
  • 超时和取消
  • Context 最佳实践

学习要点

Goroutine

// 启动 Goroutine
go func() {
    fmt.Println("Hello from goroutine")
}()

// 带 WaitGroup
var wg sync.WaitGroup
wg.Add(1)
go func() {
    defer wg.Done()
    // 执行任务
}()
wg.Wait()

Channel

// 创建 Channel
ch := make(chan int)
chBuffered := make(chan int, 10)

// 发送和接收
go func() {
    ch <- 42  // 发送
}()
value := <-ch  // 接收

// 关闭和遍历
close(ch)
for v := range ch {
    fmt.Println(v)
}

Select

select {
case v := <-ch1:
    fmt.Println("ch1:", v)
case v := <-ch2:
    fmt.Println("ch2:", v)
case <-time.After(time.Second):
    fmt.Println("超时")
default:
    fmt.Println("无数据")
}

Context

// 创建带超时的 Context
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()

// 在 Goroutine 中使用
go func(ctx context.Context) {
    select {
    case <-ctx.Done():
        fmt.Println("被取消")
    }
}(ctx)

学习建议

  1. 理解 CSP 模型:Go 的并发基于 CSP(通信顺序进程)模型
  2. 不要通过共享内存通信:通过通信来共享内存
  3. 避免 Goroutine 泄漏:确保 Goroutine 能够正常退出
  4. 合理使用锁:Channel 优先,锁在必要时使用
  5. Context 传递:Context 应该作为函数的第一个参数