golang中如何阻塞等待所有goroutines都完成
有一天,一个人问了我此问题,回头仔细翻阅了一下资料,仔细的想了一下,这个问题的解决有两种方案。
方案一:
也是推荐方案,也是官方推荐方案,涉及到一个写并发经常关注的模块sync模块,利用里面的sync.WaitGroup去做
代码如下:
package main
import(
"fmt"
"sync"
"time"
"runtime"
)
var wg sync.WaitGroup //定义一个同步等待的组
func main() {
maxProcs := runtime.NumCPU() //获取cpu个数
runtime.GOMAXPROCS(maxProcs) //限制同时运行的goroutines数量
for i:=0;i<10;i++{
wg.Add(1)//为同步等待组增加一个成员
go Printer(i)//并发一个goroutine
}
wg.Wait() //阻塞等待所有组内成员都执行完毕退栈
fmt.Println("WE DONE!!!")
}
//定义一个Printer函数用于并发
func Printer(a int)(){
time.Sleep(2000 * time.Millisecond)
fmt.Printf("i am %d\n",a)
defer wg.Done()
}
方案二:
思路也不绕路,利用的channel的阻塞机制,直接上代码了。
package main
import(
"fmt"
"time"
"runtime"
)
var num=14 //定义一工并发多少数量
var cnum chan int
func main(){
maxProcs := runtime.NumCPU()// 获取cpu个数
runtime.GOMAXPROCS(maxProcs)//限制同时运行的goroutines数量
cnum=make(chan int,num) //make一个chan,缓存为num
for i:=0;i<num;i++{
go Printer(i)
}
// 下面这个for循环的意义就是利用信道的阻塞,一直从信道里取数据,直到取得跟并发数一样的个数的数据,则视为所有goroutines完成。
for i:=0;i<num;i++{
<-cnum
}
fmt.Println("WE DONE!!!")
}
func Printer(a int)(){
time.Sleep(2000 * time.Millisecond)
fmt.Printf("i am %d\n",a)
cnum <- 1 //goroutine结束时传送一个标示给信道。
}
golang中如何阻塞等待所有goroutines都完成的更多相关文章
- Golang网络库中socket阻塞调度源码剖析
本文分析了Golang的socket文件描述符和goroutine阻塞调度的原理.代码中大部分是Go代码,小部分是汇编代码.完整理解本文需要Go语言知识,并且用Golang写过网络程序.更重要的是,需 ...
- golang 中 channel 的非阻塞访问方法
在golang中,基本的channel读写操作都是阻塞的,如果你想要非阻塞的,可以使用如下示例: 即只要在select中加入default,阻塞立即变成非阻塞: package main import ...
- java中等待所有线程都执行结束(转)
转自:http://blog.csdn.net/liweisnake/article/details/12966761 今天看到一篇文章,是关于java中如何等待所有线程都执行结束,文章总结得很好,原 ...
- java中等待所有线程都执行结束
转自:http://blog.csdn.net/liweisnake/article/details/12966761 今天看到一篇文章,是关于java中如何等待所有线程都执行结束,文章总结得很好,原 ...
- Golang控制子gorutine退出,并阻塞等待所有子gorutine全部退出
Golang控制子gorutine退出,并阻塞等待所有子gorutine全部退出 需求 程序有时需要自动重启或者重新初始化一些功能,就需要退出之前的所有子gorutine,并且要等待所有子goruti ...
- golang中锁mutex的实现
golang中的锁是通过CAS原子操作实现的,Mutex结构如下: type Mutex struct { state int32 sema uint ...
- golang 中 sync包的 WaitGroup
golang 中的 sync 包有一个很有用的功能,就是 WaitGroup 先说说 WaitGroup 的用途:它能够一直等到所有的 goroutine 执行完成,并且阻塞主线程的执行,直到所有的 ...
- golang中并发sync和channel
golang中实现并发非常简单,只需在需要并发的函数前面添加关键字"go",但是如何处理go并发机制中不同goroutine之间的同步与通信,golang 中提供了sync包和channel ...
- golang中使用Shutdown特性对http服务进行优雅退出使用总结
golang 程序启动一个 http 服务时,若服务被意外终止或中断,会让现有请求连接突然中断,未处理完成的任务也会出现不可预知的错误,这样即会造成服务硬终止:为了解决硬终止问题我们希望服务中断或退出 ...
随机推荐
- 1110 Complete Binary Tree (25 分)
Given a tree, you are supposed to tell if it is a complete binary tree. Input Specification: Each in ...
- centos 中 redis 的安装
安装流程 Wget http://download.redis.io/releases/redis-5.0.4.tar.gz tar xzf redis-5.0.4.tar.gz mv redis-5 ...
- 18.Python格式化字符串(格式化输出)
Python 提供了“%”对各种类型的数据进行格式化输出,例如如下代码: price = 108 print ("the book's price is %s" % price) ...
- python 安装-ERROR---Unable to find vcvarsall.bat
系统配置:Windows10 x64, Visual Studio 2017, Python2.7.1 报错信息:error: Unable to find vcvarsall.bat 报错原因:在生 ...
- Java中FileOutputStream流的write方法
本文为大家分享了FileOutputStream流的write方法,供大家参考,具体内容如下 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...
- Spring boot之JPA
JPA 步骤: (1)在pom.xml添加mysql,spring-data-jpa依赖 (2)在application.properties文件中配置mysql连接配置文件 (3)在applicat ...
- python3笔记十九:os和ospath模块
一:学习内容 os模块 ospath模块 获取指定目录下所有文件和目录 二:os模块 包含了普遍的操作系统功能,需要导入该模块:import os 当前所在位置目录结构为: 目录操作 1.获取当前目录 ...
- spark MLlib 概念 4: 协同过滤(CF)
1. 定义 协同过滤(Collaborative Filtering)有狭义和广义两种意义: 广义协同过滤:对来源不同的数据,根据他们的共同点做过滤处理. Collaborative filterin ...
- jquery 登录判断遇到的小问题
1.碰到的第一个问题是: 往body上加载check,用load不管用,可以用ready试试. 2.原来jquery里获取用的val(),我一直以为是value()... 尴尬 3.两个标志位是为了判 ...
- setcookie()函数
PHP PDO使用fetchAll()方法获取结果集 fetchAll()方法获取结果集中的所有行数据记录. fetchAll()方法的语法格式如下: array PDOStatement::fetc ...