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 服务时,若服务被意外终止或中断,会让现有请求连接突然中断,未处理完成的任务也会出现不可预知的错误,这样即会造成服务硬终止:为了解决硬终止问题我们希望服务中断或退出 ...
随机推荐
- python实现一个层次聚类方法
层次聚类(Hierarchical Clustering) 一.概念 层次聚类不需要指定聚类的数目,首先它是将数据中的每个实例看作一个类,然后将最相似的两个类合并,该过程迭代计算只到剩下一个类为止,类 ...
- JS框架_(JQuery.js)夜晚天空满天星星闪烁动画
百度云盘 传送门 密码:xftr 满天星星闪烁动画效果: (可用星空动画来作为页面背景,白色文字改为文章或者其他的O(∩_∩)O) <!doctype html> <html> ...
- HTML DOM的学习
请看下面的 HTML 片段: <html> <head> <title>DOM 教程</title> </head> <body> ...
- Understand RNN with TensorFlow in 7 Steps
待翻译 https://medium.com/@erikhallstrm/hello-world-rnn-83cd7105b767
- Java并发编程的艺术笔记(六)——HashMap、ConcurentHashMap的原理与实现
一.线程不安全的HashMap 多线程环境下,使用HashMap进行put操作会引起死循环(jdk1.7 Entry链表形成环形数据结构),导致CPU利用率接近100%. 结构:数组 table[]+ ...
- Linux常用命令及操作
shutdown -r now现在重启 shutdown -h now现在关机 reboot重启 startx进入图形界面 chmod +x 777 文件名 授权和可执行 777为二进制111-111 ...
- bootstrap 学习笔记(部分)
这个课程中的boostrap是3.0+版本的.(2.0与3.0有区别) bootstrap中的JS是依赖于jquery的,所以需要事先引用jquery(1.9.0版本以上). <!DOCTYPE ...
- ubuntu下mysql数据库存储路径修改
一.安装mysql ubuntu系统安装配置APT源,apt install mysql-server mysql-client 二.查看安装端口情况 sudo netstat -tap | grep ...
- 转自B站 真希望我在20岁就懂得的10个人生道理 主讲:王魄
视频地址:https://www.bilibili.com/video/av65194244?from=search&seid=15261178568916939794 这位阿姨讲得还行,特别 ...
- c#协变 抗变
public class Fa : TranOut<Fa>, TranIn<Fa> { } public class son : Fa, TranOut<son>, ...