Goroutine

进程、线程、协程的区别

进程:进程是操作系统为应用程序分配资源的最小单元。每个进程有独立的内存空间和状态。

线程:线程是进程中的一个独立执行单元。在 Go 中,一个进程可以启动多个线程,以并行执行任务。

协程:协程是 Go 语言中的一种轻量级的并发技术。它是用户态的,不需要操作系统的支持,可以在单个线程中启动多个协程,并行执行任务。协程共享同一个线程的资源,但拥有自己的栈和寄存器。

生命周期

Go 中协程之间没有严格的父子关系,协程都是平等调度的。这种设计带来了灵活性,但也需要开发者特别注意协程的生命周期管理,以避免资源泄漏或意外行为。

  1. 协程独立运行:子协程一旦启动,其生命周期与父协程无关

  2. 主协程退出程序结束:当 main 协程结束时,所有其他协程会被强制终止

  3. 无自动传播机制:父协程的取消不会自动传播给子协程

主协程退出导致子协程被强制终止

问题

1func main() {
2    go child() // 启动子协程
3    // 主协程立即退出,子协程可能来不及执行
4}
5
6func child() {
7    time.Sleep(time.Second)
8    fmt.Println("这行可能不会执行")
9}

方案:使用 WaitGroup 等待子协程完成

 1func main() {
 2    var wg sync.WaitGroup
 3    wg.Add(1)
 4    
 5    go func() {
 6        defer wg.Done()
 7        child()
 8    }()
 9    
10    wg.Wait() // 等待子协程完成
11}