sync.WaitGroup,顾名思义,等待一组goroutinue运行完毕。sync.WaitGroup声明后即可使用,它有如下方法:

  1. func (wg *WaitGroup) Add(delta int) #不能传入符数,否则引发panic
  2. func (wg *WaitGroup) Done()
  3. func (wg *WaitGroup) Wait()

一般套路是,"先统一Add, 在并发Done, 最后Wait"。中心思想是由一个goroutine或主程序来调用Add和Wait方法,其他goroutinue作为子任务调用done方法,否则会引发可能的panic异常。

sync.Once, 也是开箱即用的,声明后即可使用,只有一个方法:

  1. func (o *Once) Do(f func())

sync.Once需要注意以下两点,避免踩坑:

  1. 当多个goroutinue并发地调用同一个sync.Once实例时,如果传入的函数执行时间过长,由于sync.Once是使用锁机制,保证传入的函数只执行一次,因此会造成其他goroutinue函数的阻塞。
  2. 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的更多相关文章

  1. golang的sync.WaitGroup使用示例

    下面一段代码 len(m) 不一定会打印为 10,为什么?.如果想要 len(m) 打印为 10,应该怎么修改代码? func main() { const N = 10 m := make(map[ ...

  2. Go并发控制之sync.WaitGroup

    WaitGroup 会将main goroutine阻塞直到所有的goroutine运行结束,从而达到并发控制的目的.使用方法非常简单,真心佩服创造Golang的大师们! type WaitGroup ...

  3. sync—WaitGroup

    用途:阻塞主线程的执行,直到所有的goroutine执行完成 WaitGroup总共有三个方法:Add(delta int),Done(),Wait().简单的说一下这三个方法的作用. Add:添加或 ...

  4. golang 的 sync.WaitGroup

    WaitGroup的用途:它能够一直等到所有的goroutine执行完成,并且阻塞主线程的执行,直到所有的goroutine执行完成. 官方对它的说明如下: A WaitGroup waits for ...

  5. 《Go语言实战》笔记之协程同步 sync.WaitGroup

    原文地址(欢迎互换友链): http://www.niu12.com/article/8 sync 包提供同步 goroutine 的功能 <p>文档介绍</p><cod ...

  6. golang-----golang sync.WaitGroup解决goroutine同步

    go提供了sync包和channel来解决协程同步和通讯.新手对channel通道操作起来更容易产生死锁,如果时缓冲的channel还要考虑channel放入和取出数据的速率问题. 从字面就可以理解, ...

  7. golang sync.WaitGroup

    //阻塞,直到WaitGroup中的所以过程完成. import ( "fmt" "sync" ) func wgProcess(wg *sync.WaitGr ...

  8. Golang sync.WaitGroup的用法

    0x01 介绍 经常会看到以下了代码: 12345678910111213 package main import ( "fmt" "time") func m ...

  9. Golang的sync.WaitGroup 实现逻辑和源码解析

    在Golang中,WaitGroup主要用来做go Routine的等待,当启动多个go程序,通过waitgroup可以等待所有go程序结束后再执行后面的代码逻辑,比如: func Main() { ...

随机推荐

  1. Java 学习之集合类(Collections)

    Collection(集合类) 我们是使用数组来保存数据,但是他的长度一旦创建,就已经确定了,当我们要动态传入穿值,数组就有些局限了,集合类就孕育而生:所谓集合,就是来保存,盛装数据,也可称为容器类: ...

  2. 使用PostSharp在.NET平台上实现AOP(转)

    出处:https://www.cnblogs.com/leoo2sk/archive/2010/11/30/aop-postsharp.html 摘要 本文首先介绍AOP(面向方面编程)的相关概念及理 ...

  3. 使用express框架和mongoose在MongoDB删除数据

    使用remove()删除数据 remove({},function(err,doc){})  // 删除所有数据 remove({age:18},function(err,doc){}); //删除指 ...

  4. IntelliJ IDEA 2017版 spring-boot 2.03 去除控制台logo;去除springboot 图标;去除springboot 图

    1.控制台出现logo图标 2.如果不喜欢,如何去除这个logo 在其Application中进行设置 package com.springboot.logo; import org.springfr ...

  5. spring mvc 文件上传工具类

    虽然文件上传在框架中,已经不是什么困难的事情了,但自己还是开发了一个文件上传工具类,是基于springmvc文件上传的. 工具类只需要传入需要的两个参数,就可以上传到任何想要上传的路径: 参数1:Ht ...

  6. RestTemplate将响应数据转换为具有泛型的类对象

    前言: 重要,RestTemplate在SpringBoot项目里即便通过HttpMessageConverters添加了Fastjson且优先级比jackson要高也不会在RestTemplate里 ...

  7. 利用cglib包实现Spring中aop的<aop:advisor>功能

    一:前言 还有<aop:before>/<aop:after>/<aop:around>的没有实现,不过根<aop:advisor>是差不多的,就是要额 ...

  8. java通过sftp对linux服务器文件夹进行操作

    本文主要讲sftp对linux服务器的文件和文件夹进行操作,windows server 服务器不支持. package com.lx.ftp; import java.io.File; import ...

  9. Sprinig泛型依赖注入

    在父类中建立关系 (spring4.x以上版本) package com.spring.annotation.generic; import org.springframework.beans.fac ...

  10. python_day1_python简单介绍

    一.python解释器的种类 我们都知道python是一种解释型的语言,那python在执行的过程中必须要通过解释器来执行,那python的解释器到底分为哪些呢? 1.Cpython CPython是 ...