sync.WaitGroup和sync.Once
sync.WaitGroup,顾名思义,等待一组goroutinue运行完毕。sync.WaitGroup声明后即可使用,它有如下方法:
- func (wg *WaitGroup) Add(delta int) #不能传入符数,否则引发panic
- func (wg *WaitGroup) Done()
- func (wg *WaitGroup) Wait()
一般套路是,"先统一Add, 在并发Done, 最后Wait"。中心思想是由一个goroutine或主程序来调用Add和Wait方法,其他goroutinue作为子任务调用done方法,否则会引发可能的panic异常。
sync.Once, 也是开箱即用的,声明后即可使用,只有一个方法:
- func (o *Once) Do(f func())
sync.Once需要注意以下两点,避免踩坑:
- 当多个goroutinue并发地调用同一个sync.Once实例时,如果传入的函数执行时间过长,由于sync.Once是使用锁机制,保证传入的函数只执行一次,因此会造成其他goroutinue函数的阻塞。
- sync.Once 有一个done的unint32的字段,取值只有0和1。只要Do方法执行完成,done就由0变为1。值得注意的是done由defer保证执行后一定会是1。
package main
import "sync"
import "fmt"
import "sync/atomic"
import "time"
const PI = 3.14
var w sync.WaitGroup
var once sync.Once
var doneTaskCount int32
func calCircleCircum(r float64, ret *float64) {
defer w.Done()
*ret = PI * r
atomic.AddInt32(&doneTaskCount, 1)
time.Sleep(time.Millisecond * 2000)
}
func calRectangleCircum(width float64, long float64, ret *float64) {
defer w.Done()
*ret = 2 * (long + width)
atomic.AddInt32(&doneTaskCount, 1)
time.Sleep(time.Millisecond * 1000)
}
func printResults(circleRet *float64, rectangleRet *float64) {
once.Do(func(){
for atomic.LoadInt32(&doneTaskCount) !=2 {
fmt.Println("Wait sub task done.....")
time.Sleep(time.Millisecond * 200)
}
})
fmt.Printf("the cicle circumference is %1.2f\n", *circleRet)
fmt.Printf("the rectangle circumference is %1.2f\n", *rectangleRet)
}
func main() {
circleRet := 0.0
rectangleRet := 0.0
w.Add(2)
go printResults(&circleRet, &rectangleRet)
go calCircleCircum(2.0, &circleRet)
go calRectangleCircum(2.0, 3.0, &rectangleRet)
w.Wait()
}
sync.WaitGroup和sync.Once的更多相关文章
- golang的sync.WaitGroup使用示例
下面一段代码 len(m) 不一定会打印为 10,为什么?.如果想要 len(m) 打印为 10,应该怎么修改代码? func main() { const N = 10 m := make(map[ ...
- Go并发控制之sync.WaitGroup
WaitGroup 会将main goroutine阻塞直到所有的goroutine运行结束,从而达到并发控制的目的.使用方法非常简单,真心佩服创造Golang的大师们! type WaitGroup ...
- sync—WaitGroup
用途:阻塞主线程的执行,直到所有的goroutine执行完成 WaitGroup总共有三个方法:Add(delta int),Done(),Wait().简单的说一下这三个方法的作用. Add:添加或 ...
- golang 的 sync.WaitGroup
WaitGroup的用途:它能够一直等到所有的goroutine执行完成,并且阻塞主线程的执行,直到所有的goroutine执行完成. 官方对它的说明如下: A WaitGroup waits for ...
- 《Go语言实战》笔记之协程同步 sync.WaitGroup
原文地址(欢迎互换友链): http://www.niu12.com/article/8 sync 包提供同步 goroutine 的功能 <p>文档介绍</p><cod ...
- golang-----golang sync.WaitGroup解决goroutine同步
go提供了sync包和channel来解决协程同步和通讯.新手对channel通道操作起来更容易产生死锁,如果时缓冲的channel还要考虑channel放入和取出数据的速率问题. 从字面就可以理解, ...
- golang sync.WaitGroup
//阻塞,直到WaitGroup中的所以过程完成. import ( "fmt" "sync" ) func wgProcess(wg *sync.WaitGr ...
- Golang sync.WaitGroup的用法
0x01 介绍 经常会看到以下了代码: 12345678910111213 package main import ( "fmt" "time") func m ...
- Golang的sync.WaitGroup 实现逻辑和源码解析
在Golang中,WaitGroup主要用来做go Routine的等待,当启动多个go程序,通过waitgroup可以等待所有go程序结束后再执行后面的代码逻辑,比如: func Main() { ...
随机推荐
- ThinkPHP redirect 传参
重定向带参 $this->redirect('pay/under_line_success',array('order_id'=>$stuInfo),5,'页面跳转中….'); 第一个参数 ...
- zookeeper 单机集成部署
概述 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等,是很多分布式的基础设置,比如dubbo,k ...
- ubuntu16.04无法关机解决方法
11 down vote In my case these simple steps worked for me fine: Press Ctrl+Alt+T to go to a termina ...
- maven打包某个分支的包
maven打某个分支的包命令: mvn clean install -Dmaven.test.skip=true -Pdevelop
- [转]两表join的multi update语句在MySQL中的执行流程分析
出自:http://hedengcheng.com/?p=209 两表join的multi update语句,执行结果与预计不一致的分析过程 — multi update结论在实际应用中,不要轻易使用 ...
- GIS矢量数据化简:一种改进的道格拉斯-普克算法以及C++实现
GIS领域的同志都知道,传统的道格拉斯-普克算法都是递归实现.然而有时候递归的层次太深的话会出现栈溢出的情况.在此,介绍一种非递归的算法. 要将递归算法改为非递归算法,一般情况下分为两种场景.第一种是 ...
- 1098 Insertion or Heap Sort
1098 Insertion or Heap Sort (25 分) According to Wikipedia: Insertion sort iterates, consuming one in ...
- zend studio 修改字体大小
第一步:进入设置窗口 windows -> preferences第二步:进入修改字体的选项卡. General -> Appearance -> Colors and ...
- How to resolve "your security settings have blocked an untrusted application from running" in Mac
If you encounter the error "your security settings have blocked an untrusted application from r ...
- (BestCoder Round #64 (div.2))Array
BestCoder Round #64 (div.2) Array 问题描述 Vicky是个热爱数学的魔法师,拥有复制创造的能力. 一开始他拥有一个数列{1}.每过一天,他将他当天的数列复制一遍,放在 ...