Go如何保证gorountine执行完毕后继续执行
来源:互联网 发布:黄金坑选股公式源码 编辑:程序博客网 时间:2024/06/07 23:04
Gorountine和channel是go语言最核心的功能,这个功能保证了go强大的并发执行能力。如果你想在你继续执行你的goroutine之前等待所有的goroutines执行完毕,你该如何使用go语言解决这样一个问题呢?
下面,我将给出三中解决方案。其中,最有解决方案是sync.WaitGroup
。
程序函数等待
利用time包中的Sleep方法等待一段时间,这样就引起另外一个问题,到底该等待多久呢?
下面是程序的实现。
func receiveMsg(){ msg := make(chan string) go func(){ time.Sleep(time.Second * 1) msg <- "goroutine 1" }() go func(){ time.Sleep(time.Second * 2) msg <- "goroutine 2" }() go func(){ time.Sleep(time.Second * 3) msg <- "goroutine 3" }() go func(){ for i := range msg { fmt.Println("message :", i) } }() time.Sleep(time.Second * 4)}func main() { receiveMsg()}
功能上解决了问题,但是,如果没法知道所有的goroutine总共执行,还是没有从根本上解决问题。利用channel,可以有一个改良版的解决方案。
channel等待
首先,看看具体的程序实现。
func receiveMsg2(){ msg := make(chan string) done := make(chan bool) go func(){ time.Sleep(time.Second * 3) msg <- "goroutine 1" done <- true }() go func(){ time.Sleep(time.Second * 2) msg <- "goroutine 2" done <- true }() go func(){ time.Sleep(time.Second * 1) msg <- "goroutine 3" done <- true }() go func(){ //This statement is to make sure that all message is received. time.Sleep(time.Second * 3) for i := range msg { fmt.Println("message :", i) } }() for j := 0 ; j < 3; j++ { <-done }}func main() { receiveMsg2()}
从上面程序而言,程序添加了time.Sleep(time.Second * 1) 。添加这行代码是为了保证消息被完全接受(打印到控制台)。由这个程序的解决方案引出了另外一个问题:加入我们不知道到底有多少个goroutine该怎么办?
sync.WaitGroup
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.
使用sync.WaitGroup
有四个步骤:
1. 创建一个新的sync.WaitGroup
实例wg
(假定代码,下面描述要用到);
2. 当需要使用goroutine的时候,调用wg.Add(1)
(使用一次调用一次,如果知道到有N个goroutine,可以直接设置对应的N个);
3. 当goroutine执行完毕前,需要告诉WaitGroup执行完毕,调用对应代码defer wg.Done()
;
4. 在需要等待所有goroutine执行完毕时,调用代码wg.Wait()
。
func receiveMsg3(){ msg := make(chan string) var wg sync.WaitGroup wg.Add(3) go func(){ defer wg.Done() time.Sleep(time.Second * 3) msg <- "goroutine 1" }() go func(){ defer wg.Done() time.Sleep(time.Second * 2) msg <- "goroutine 2" }() go func(){ defer wg.Done() time.Sleep(time.Second * 1) msg <- "goroutine 3" }() go func(){ time.Sleep(time.Second * 3) for i := range msg { fmt.Println("message :", i) } }() wg.Wait()}func main() { receiveMsg3()}
通过上面的代码就是按照这4个步骤来构建整个函数的,运用sync.WaitGroup
可以顺利实现并发等待操作。
欢迎订阅微信公众号
- Go如何保证gorountine执行完毕后继续执行
- 关闭终端后保证服务仍然在后台继续执行
- 如何在css加载完毕后,再执行后续代码
- 如何保存python程序执行完毕后的全部变量
- 主线程等待所有子线程执行完毕后再继续的问题
- C++ 调用exe,可等待调用的exe执行完毕后才继续执行父进程 CreateProcess
- 异常结束后继续执行
- su后继续执行脚本
- 如何保证线程顺序执行?
- 执行完毕后重新加载此页面?
- WebBrowser加载完毕后再往下执行
- AngularJs渲染完毕后执行指定操作
- WebBrowser让DocumentCompleted事件执行完毕后再往下执行
- 主线程等待子线程执行完毕后再执行
- bat批处理ant执行完毕后执行其他命令
- android sql 顺序执行问题,怎么才能执行第一个完毕,才能继续执行第二个
- 如何让cmd窗口执行上一条命令后暂停会继续执行下一条命令
- [Delphi]如何判断线程已执行完毕?
- 解决使用CSDN下载东西时,点击直接下载没有反应的问题
- SVN客户端的使用
- 《阿里巴巴Java开发手册(正式版)》--安全规约
- Hive扩展功能(八)--表的索引
- Android官方的下拉刷新SwipeRefreshLayout
- Go如何保证gorountine执行完毕后继续执行
- Nodemanager in unhealthy state
- SVN客户端的安装
- 欢迎使用CSDN-markdown编辑器
- 4445: [Scoi2015]小凸想跑步
- GDKOI划水记
- 通过ajax请求springmvc,将值显示在select下拉框中
- SVN(服务器)安装
- js中的作用域和执行上下文的区别