Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > Go语言等待组sync.WaitGrou

Go语言等待组sync.WaitGrou的使用示例

作者:C语言中文网

本文主要介绍了Go语言等待组sync.WaitGrou的使用示例,sync.WaitGroup只有3个方法,Add(),Done(),Wait(),下面就来具体的介绍一下如何使用,感兴趣的可以了解一下

Go语言中除了可以使用通道(channel)和互斥锁进行两个并发程序间的同步外,还可以使用等待组进行多个任务的同步,等待组可以保证在并发环境中完成指定数量的任务

在 sync.WaitGroup(等待组)类型中,每个 sync.WaitGroup 值在内部维护着一个计数,此计数的初始默认值为零。

等待组有下面几个方法可用,如下表所示。

方法名功能
(wg * WaitGroup) Add(delta int)等待组的计数器 +1
(wg * WaitGroup) Done()等待组的计数器 -1
(wg * WaitGroup) Wait()当等待组计数器不等于 0 时阻塞直到变 0。

对于一个可寻址的 sync.WaitGroup 值 wg:

等待组内部拥有一个计数器,计数器的值可以通过方法调用实现计数器的增加和减少。当我们添加了 N 个并发任务进行工作时,就将等待组的计数器值增加 N。每个任务完成时,这个值减 1。同时,在另外一个 goroutine 中等待这个等待组的计数器值为 0 时,表示所有任务已经完成。

下面的代码演示了这一过程:

package main
import (
    "fmt"
    "net/http"
    "sync"
)
func main() {
    // 声明一个等待组
    var wg sync.WaitGroup
    // 准备一系列的网站地址
    var urls = []string{
        "http://www.github.com/",
        "https://www.qiniu.com/",
        "https://www.golangtc.com/",
    }
    // 遍历这些地址
    for _, url := range urls {
        // 每一个任务开始时, 将等待组增加1
        wg.Add(1)
        // 开启一个并发
        go func(url string) {
            // 使用defer, 表示函数完成时将等待组值减1
            defer wg.Done()
            // 使用http访问提供的地址
            _, err := http.Get(url)
            // 访问完成后, 打印地址和可能发生的错误
            fmt.Println(url, err)
            // 通过参数传递url地址
        }(url)
    }
    // 等待所有的任务完成
    wg.Wait()
    fmt.Println("over")
}

代码说明如下:

例子

同时开三个协程去请求网页, 等三个请求都完成后才继续 Wait 之后的工作

var wg sync.WaitGroup
var urls = []string{
   "http://www.golang.org/",
   "http://www.google.com/",
   "http://www.somestupidname.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)
   }(url)
}
// Wait for all HTTP fetches to complete. 
wg.Wait()

或者下面的代码
用于测试 给chan发送 1千万次,并接受1千万次的性能

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

const (
   num = 10000000
)

func main() {
   TestFunc("testchan", TestChan)
}

func TestFunc(name string, f func()) {
   st := time.Now().UnixNano()
   f()
   fmt.Printf("task %s cost %d \r\n", name, (time.Now().UnixNano()-st)/int64(time.Millisecond))
}

func TestChan() {
   var wg sync.WaitGroup
   c := make(chan string)
   wg.Add(1)

   go func() {
      for _ = range c {
      }
      wg.Done()
   }()

   for i := 0; i < num; i++ {
      c <- "123"
   }
   close(c)
   wg.Wait()
}

到此这篇关于Go语言等待组sync.WaitGrou的使用示例的文章就介绍到这了,更多相关Go语言等待组sync.WaitGrou内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

您可能感兴趣的文章:
阅读全文