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 服务时,若服务被意外终止或中断,会让现有请求连接突然中断,未处理完成的任务也会出现不可预知的错误,这样即会造成服务硬终止:为了解决硬终止问题我们希望服务中断或退出 ...
随机推荐
- 在vue中如何安装使用Vant
---恢复内容开始--- Vant中文文档地址:https://youzan.github.io/vant-weapp 1.创建Vue项目之后,运行安装命令:13:47:04 npm i vant - ...
- SPP框架的基本使用
入职两天 Day1.Day2: 学习SPP框架 SPP是什么? SPP提供了一系列的基础功能,是一个通用的网络服务器运行框架.主要由proxy,worker,controller三个模块组成.它提供A ...
- 编译一个需要用特定key前面的应用程序
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # Build all java files in the java subdirectory L ...
- 剑指offer32----之字形打印一颗二叉树
题目 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推. 思路 在这里我们如果单纯的使用队列去弄的话,会很 ...
- Mysql超强卸载
1.控制面板——>所有控制面板项——>程序和功能,卸载mysql server! 2.删除MySQL文件,尤其是ProgramData里面的隐藏文件MySQL,我当时没有删除,重新安装My ...
- 利用python的图像分块与拼接
import os import matplotlib.pyplot as plt import cv2 import numpy as np def divide_img(img_path, img ...
- jQuery .submit()
.submit() Events > Form Events | Forms .submit( handler )Returns: jQuery Description: Bind an eve ...
- webpack 最新版
之前说过老的版本,webpack@3.8.1 这个版本,现在我们来看看,新版本和老版本的区别 webpack 4 以上的版本 npm 全称 node package manager (node 包管理 ...
- C# 防火墙操作之启用与关闭
通过代码操作防火墙的方式有两种:一是代码操作修改注册表启用或关闭防火墙:二是直接操作防火墙对象来启用或关闭防火墙.不论哪一种方式,都需要使用管理员权限,所以操作前需要判断程序是否具有管理员权限. 1. ...
- Linux命令之grep用法详解:grep与正则表达式 [转]
正则表达式与通配符不一样,它们表示的含义并不相同. grep命令的选项用于对搜索过程进行补充说明.grep命令的模式十分灵活,可以是字符串.变量,还可以是正则表达式. 无论模式是何种形式,只要模式中包 ...