Go语言基础之sync.WaitGroup

WaitGroup用于等待一组线程的结束。父线程调用Add方法来设定应等待的线程的数量,每一次执行Add都会增加线程组的数量。每个被等待的线程在结束时应调用Done方法。同时,主线程里可以调用Wait方法阻塞至所有线程结束。

如果你有多个goroutine并发执行某项操作,但是下方的代码需要等待这些并发的操作执行完成之后才能够执行,那么你可以使用sync.WaitGroup,因为它比Sleep更加有效,并且稳定

方法介绍

1. func (*WaitGroup) Add(delta int)

Add方法向内部计数加上delta,delta可以是负数;如果内部计数器变为0,Wait方法阻塞等待的所有线程都会释放,如果计数器小于0,方法panic。注意Add加上正数的调用应在Wait之前,否则Wait可能只会等待很少的线程。一般来说本方法应在创建新的线程或者其他应等待的事件之前调用。

添加或者减少等待goroutine的数量

2. func (*WaitGroup) Done

Done方法减少WaitGroup计数器的值,应在线程的最后执行,Done的执行应标志着一个goroutine的结束

相当于Add(-1)

3. func (*WaitGroup) Wait

Wait方法阻塞直到WaitGroup计数器减为0。如果WaitGroup不为0,那么程序就会一直阻塞在Wait函数这里

google官方示例:

package main

import (
    "fmt"
    "sync"
    "net/http"
)

func main() {
    var wg sync.WaitGroup
    var urls = []string{
            "http://www.golang.org/",
            "http://www.google.com/",
            "http://www.baiyuxiong.com/",
    }
    for _, url := range urls {
            // Increment the WaitGroup counter.
            wg.Add(1)
            // Launch a goroutine to fetch the URL.
            go func(url string) {
                    // Decrement the counter when the goroutine completes.
                    defer wg.Done()
                    // Fetch the URL.
                    http.Get(url)
            fmt.Println(url);
            }(url)
    }
    // Wait for all HTTP fetches to complete.
    wg.Wait()
    fmt.Println("over");
}

代码执行结果为:

http://www.baiyuxiong.com/
http://www.google.com/
http://www.golang.org/
over

从执行结果可看出:

1、取三个网址信息的时候,结果显示顺序与for循环的顺序没有必然关系。
2、三个goroutine全部执行完成后,wg.Wait()才停止等待,继续执行并打印出over字符。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容