Golang 程序中使用 sync.WaitGroup 同步多个 Goroutine

字节幂 · · 2314 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

编写并发的程序时,经常会遇到需要同步多个协程/线程的状态/数据的问题。在 Golang 程序中同步多个 Goroutine 的最简单的办法就是使用 sync.WaitGroup。

下面是官网的介绍:

A WaitGroup waits for a collection of goroutines to finish. The main goroutine calls Add to set the number of goroutines to wait for. Then each of the goroutines runs and calls Done when finished. At the same time, Wait can be used to block until all goroutines have finished.

从中我们可以提取出几点关键信息:

  1. WaitGroup 可以用于等待一系列的 Goroutine 完成任务;
  2. Add 方法须在 main goroutine 中调用;
  3. Done 方法须在其它新建的 goroutine 中调用;
  4. Wait 方法可以阻塞等待直至其它 goroutine 完成;

Talk is cheap. Show me the code.

package main

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

func TaskA(wg *sync.WaitGroup) {
    defer wg.Done()
    time.Sleep(1 * time.Second)
    fmt.Println("task a done...")
}

func TaskB(wg *sync.WaitGroup) {
    defer wg.Done()
    time.Sleep(3 * time.Second)
    fmt.Println("task b done...")
}

func TaskC(wg *sync.WaitGroup) {
    defer wg.Done()
    time.Sleep(5 * time.Second)
    fmt.Println("task c done...")
}

func main() {
    var wg sync.WaitGroup

    //开启一个 goroutine 前,在 main goroutine 中调用 wg.Add
    //为什么强调一定要在 main goroutine 中调用 wg.Add,而不能在
    //新建的 goroutine 中调用呢?我的理解是如果延迟到新建的
    //goroutine 中调用 wg.Add 就有可能造成 wg.Wait 先执行。若是
    //如此,必定不能达到如期的效果。
    wg.Add(1)
    //传递给 goroutine 的 WaitGroup 变量必须为指针类型,因为在
    //Golang 中所有的函数参数都是值传递,也就是在函数体内会复制一
    //份参数的副本。如果不使用指针类型就无法引用到同一个 WaitGroup
    //变量,便也不能依赖 WaitGroup 来实现同步了。
    go TaskA(&wg)

    wg.Add(1)
    go TaskC(&wg)

    wg.Add(1)
    go TaskB(&wg)

    //阻塞等待直至所有其它的 goroutine 都已执行完毕
    wg.Wait()
    fmt.Println("all the tasks done...")
}


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:字节幂

查看原文:Golang 程序中使用 sync.WaitGroup 同步多个 Goroutine

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2314 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传