Bootstrap

GO:go func

Go:用于同步和并发控制的几种常见锁

1. Goroutine 的基础

1.1 定义
  • Goroutine 是由 Go 运行时管理的轻量级线程。
  • 启动一个 goroutine 只需要极小的内存(几 KB),而不像系统线程那样需要几 MB。
1.2 启动
  • go func() 启动一个新的 goroutine,函数体在新的 goroutine 中并发执行。

  • 例如:

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

2. Go Scheduler (调度器)

2.1 调度器角色
  • Go 运行时包含一个调度器,负责管理和调度所有的 goroutine。
  • 调度器确保所有的 goroutine 能够公平地获取执行时间。
2.2 M:N 模型
  • Go 采用 M:N 模型,将 M 个 goroutine 映射到 N 个系统线程上。
  • 调度器使用工作窃取算法,使得 goroutine 能够在多个线程之间平衡负载。

3. Goroutine 的执行流程

3.1 创建
  • 使用 go 关键字启动 goroutine 时,运行时系统会创建一个新的 G(表示 goroutine)对象,并将其添加到运行队列。
3.2 调度
  • 调度器根据系统资源和 goroutine 的优先级,将 G 对象分配给 P(Processor),P 代表逻辑处理器。
  • P 再将 G 分配给 M(Machine),M 代表实际的操作系统线程。
3.3 执行
  • M 执行 G 中的代码,当 G 阻塞或完成时,M 将其从 P 的运行队列中移除,并寻找下一个 G 执行。

4. 并发与同步

4.1 并发
  • 多个 goroutine 可以同时运行,并利用多核处理器提升性能。
  • 例如,在一个 HTTP 服务器中,每个请求可以启动一个新的 goroutine 来处理,从而实现高并发处理。
4.2 同步
  • 当多个 goroutine 需要访问共享资源时,需要同步机制来避免竞态条件。
  • Go 提供了多种同步原语,如 sync.Mutexsync.WaitGroupchannels

5. Channels (通道)

5.1 定义
  • 通道是 Go 语言提供的一种用于 goroutine 之间通信的机制。
  • 通道允许安全地在多个 goroutine 之间传递数据。
5.2 使用
  • 使用 make 函数创建通道:

    ch := make(chan int)
    
  • 向通道发送数据和从通道接收数据:

    go func() {
        ch <- 42 // 发送数据到通道
    }()
    
    value := <-ch // 从通道接收数据
    fmt.Println(value)
    

6. Goroutine 的生命周期管理

6.1 启动
  • 启动 goroutine 非常简单,使用 go 关键字。
6.2 运行
  • 调度器负责管理和调度 goroutine 的执行。
  • Goroutine 可以随时被调度器挂起和恢复。
6.3 终止
  • 当 goroutine 的函数体执行完毕后,goroutine 自动终止。
  • 必须小心管理 goroutine 的生命周期,避免 goroutine 泄露(即 goroutine 持续运行但无法终止)。

7. 实践中的注意事项

7.1 锁与同步
  • 在需要共享数据时,使用 sync.Mutex 保护临界区。
  • 使用 sync.WaitGroup 等待一组 goroutine 完成。
7.2 防止泄露
  • 确保每个 goroutine 都有退出条件,避免无限循环或阻塞。
;