GO教程-WaitGroup|Go主题月

147 阅读1分钟

本文为翻译文章

原文地址:golangbot.com/buffered-ch…

WaitGroup

WaitGroup 用于等待 Goroutine 的集合完成执行。在所有 Goroutine 执行完成前,才会解除阻塞。假设我们从主 Goroutine 派生了 3 个并发执行的 Goroutine。主Goroutine必须等待其他3个Goroutine完成后才能终止。这可以使用 WaitGroup 来完成。

代码示例:

package main

import (  
    "fmt"
    "sync"
    "time"
)

func process(i int, wg *sync.WaitGroup) {  
    fmt.Println("started Goroutine ", i)
    time.Sleep(2 * time.Second)
    fmt.Printf("Goroutine %d ended\n", i)
    wg.Done()
}

func main() {  
    no := 3
    var wg sync.WaitGroup
    for i := 0; i < no; i++ {
        wg.Add(1)
        go process(i, &wg)
    }
    wg.Wait()
    fmt.Println("All go routines finished executing")
}

WaitGroup 是一种结构类型,我们在创建了 WaitGroup 类型的零值变量。WaitGroup 的工作方式是使用计数器。当我们在 WaitGroup 上调用 Add 并将其传递为 int 时,WaitGroup 的计数器将增加传递给 Add 的值。减少计数器的方法是通过在 WaitGroup 上调用 Done() 方法。Wait() 方法阻止 Goroutine 在其中被调用,直到计数器变为零为止。

在上面的程序中,我们调用 wg.Add(1)。在 for 循环内循环 3 次。因此,计数器现在变为 3。for 循环还会生成 3 个进程 Goroutine,然后调用 wg.Wait()。 使主 Goroutine 等待直到计数器变为零。通过 Goroutine 进程中对 wg.Done 的调用来减少计数器。一旦所有 3 个生成的 Goroutine 都完成了执行,即 wg.Done() 被调用了 3 次,计数器将变为零,并且主 Goroutine 将被解除阻塞。

在主 Goroutine 循环体中传递 wg 的指针很重要。如果未传递指针,则每个 Goroutine 将具有其自己的 WaitGroup 副本,并且在完成执行时不会通知主 Goroutine。

程序输出:

started Goroutine  2  
started Goroutine  0  
started Goroutine  1  
Goroutine 0 ended  
Goroutine 2 ended  
Goroutine 1 ended  
All go routines finished executing  

您的输出可能与我的输出不同,因为 Goroutines 的执行顺序可能会有所不同:)。