GO sync.WaitGroup

需求

执行完所有子函数后退出主程序

#1. 串行执行

import (
    "fmt"
    "time"
)
func f1Sleep(val int) {
    time.Sleep(time.Duration(val))
    fmt.Println(val)
}

func try0() {
    fmt.Println("Start")
    start := time.Now()
    arr := []int{1, 7, 3, 2, 5}
    for _, v := range arr {
        f1Sleep(v * 1000000000)
    }
    end := time.Now()
    fmt.Println("Done", end.Sub(start))
}

func main() {
    try0()
}

执行:

Start
1000000000
7000000000
3000000000
2000000000
5000000000
Done 18.019475023s

问题:性能慢

#2. 并发执行

import (
    "fmt"
    "time"
)

func f1Sleep(val int) {
    time.Sleep(time.Duration(val))
    fmt.Println(val)
}

func try0() {
    fmt.Println("Start")
    start := time.Now()
    arr := []int{1, 7, 3, 2, 5}
    for _, v := range arr {
        go f1Sleep(v * 1000000000)
    }
    time.Sleep(10 * 1000000000)
    end := time.Now()
    fmt.Println("Done", end.Sub(start))
}

func main() {
    try0()
}

执行:

Start
1000000000
2000000000
3000000000
5000000000
7000000000
Done 10.004520653s

问题:主程序到底sleep多杀,还得自己控制,无法智能控制

sync.WaitGroup 解决协程同步和通讯

#3. 并发执行

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

var wg sync.WaitGroup

func f1Sleep(val int) {
    defer wg.Done()
    time.Sleep(time.Duration(val))
    fmt.Println(val)
}

func try1() {
    fmt.Println("Start")
    start := time.Now()
    arr := []int{1, 7, 3, 2, 5}
    for _, v := range arr {
        wg.Add(1)
        go f1Sleep(v * 1000000000)
    }
    wg.Wait()
    end := time.Now()
    fmt.Println("Done", end.Sub(start))
}

func main() {
    try1()
}

执行:

Start
1000000000
2000000000
3000000000
5000000000
7000000000
Done 7.003296504s

sync.WaitGroup只有3个方法:

  • Add():添加计数中
  • Done():是Add(-1)的别名,用途是减掉一个计数
  • Wait():计数不为0时阻塞的运行

其他知识点

#1 计算时间差

start := time.Now()

// pass

end := time.Now()

end.Sub(start)

 

#2 sleep参数单位是:Duration, 是纳秒

1秒=1000毫秒(ms)

1秒=1,000,000 微秒(μs)

1秒=1,000,000,000 纳秒(ns)

 

posted @ 2022-02-04 18:12  jihite  阅读(77)  评论(0编辑  收藏  举报