Golang等待协程运行结束

sync.WaitGroup可以使得我们很优雅的等待协程的退出

写一个普通的例子。下面的例子中,say函数中的字符串不会输出,因为main函数也是一个协程,say函数相当于一个子协程,父协程运行完退出后,子协程也会退出,并不会等待子协程中的任务完成,而要想执行完子协程中的任务,最简单的方法是让父协程等待一段时间,子协程可以在这段时间内执行完任务。去掉下面的注释后,say函数就可以执行完内部的任务。

package main

import (
	"fmt"
	"time"
)

func say() {
	fmt.Println("hello world")
}

func main() {
	for i := 0; i < 10; i++ {
		go say()
	}
	fmt.Println("I Love You")
	// time.Sleep(time.Second)  // 去掉注释
}

但是,我们并不知道子协程要执行多长时间,当执行I/O操作时,我们无法确保准确的时间,所以以上的方法不能用于正常的逻辑中。

此时我们可以使用sync.WaitGroup来控制,该对象主要维护一个计数器。该对象里面有三个重要的方法,(wg * WaitGroup) Add(delta int)方法可以指定计数器数值,计数器的数值决定了子协程的个数,该函数应该在父协程中使用;(wg *WaitGroup) Done()方法使得计数器 -1 ,该函数应该在子协程中使用;(wg *WaitGroup) Wait()方法用于阻塞父协程,直到等待计数器减到0时,父协程才可以继续往下执行,该函数应该用于父协程。

package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup  // 定义全局的结构体变量

func say() {
	defer wg.Done()  // 计数器 -1
	fmt.Println("hello world")
}

func main() {
	wg.Add(5)  // 计数器为5
	for i := 0; i < 5; i++ {
		go say()
	}
	fmt.Println("I Love You")
	wg.Wait()  // 阻塞父协程
	fmt.Println("I Love You")
}
/* 结果
I Love You
hello world
hello world
hello world
hello world
hello world
I Love You
*/
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值