all goroutines are asleep - deadlock

简单使用:

package main

import (
"sync"
) type httpPkg struct{} func (httpPkg) Get(url string) {} var http httpPkg func main() {
var wg sync.WaitGroup
var urls = []string{
"http://www.golang.org/",
"http://www.google.com/",
"http://www.somestupidname.com/",
}
for _, url := range urls {
// Increment the WaitGroup counter.
wg.Add(1)
// Launch a goroutine to fetch the URL.
go func(url string) {
// Decrement the counter when the goroutine completes.
defer wg.Done()
// Fetch the URL.
http.Get(url)
}(url)
}
// Wait for all HTTP fetches to complete.
wg.Wait()
}

这是golang官网上的例子

跟java的CountdownLatch差不多,也是阻塞等待所有任务完成之后再继续执行。

简单使用就是在创建一个任务的时候wg.Add(1), 任务完成的时候使用wg.Done()来将任务减一。使用wg.Wait()来阻塞等待所有任务完成。

然后我就写了一个例子:

func main() {
var wg sync.WaitGroup
ch := make(chan int, 1000)
for i := 0; i < 1000; i++ {
wg.Add(1)
go doSomething(i, wg, ch)
}
wg.Wait()
fmt.Println("all done")
for i := 0; i < 1000; i++ {
dd := <-ch
fmt.Println("from ch:"+strconv.Itoa(dd))
}
} func doSomething(index int, wg sync.WaitGroup, ch chan int) {
defer wg.Done()
fmt.Println("start done:" + strconv.Itoa(index))
//time.Sleep(20 * time.Millisecond)
ch <- index
}

然后就报错了:

fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc42001608c)
/usr/local/Cellar/go/1.10.3/libexec/src/runtime/sema.go:56 +0x39
sync.(*WaitGroup).Wait(0xc420016080)
/usr/local/Cellar/go/1.10.3/libexec/src/sync/waitgroup.go:129 +0x72
main.main()
/Users/taoli/go/src/github.com/c60/cai/tx_gorutine.go:16 +0xea

怎么回事,他说死锁了。

原来这是说,所有的协程都运行完了,你这边还在等待。

什么原因导致的呢?

原来是golang里如果方法传递的不是地址,那么就会做一个拷贝,所以这里调用的wg根本就不是一个对象。

传递的地方传递地址就可以了:

go doSomething(i, &wg, ch)

func doSomething(index int, wg *sync.WaitGroup, ch chan int) {

作者:ironman_
链接:https://www.jianshu.com/p/4c2c80076094
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

sync.WaitGroup的使用以及坑的更多相关文章

  1. Golang中WaitGroup使用的一点坑

    Golang中WaitGroup使用的一点坑 Golang 中的 WaitGroup 一直是同步 goroutine 的推荐实践.自己用了两年多也没遇到过什么问题.直到一天午睡后,同事扔过来一段奇怪的 ...

  2. sync.WaitGroup和sync.Once

    sync.WaitGroup,顾名思义,等待一组goroutinue运行完毕.sync.WaitGroup声明后即可使用,它有如下方法: func (wg *WaitGroup) Add(delta ...

  3. Go并发控制之sync.WaitGroup

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

  4. sync—WaitGroup

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

  5. golang 的 sync.WaitGroup

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

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

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

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

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

  8. golang sync.WaitGroup

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

  9. Golang sync.WaitGroup的用法

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

随机推荐

  1. Charles 抓包(Charles二)

    前面安装了Charles,并初步配置了一下:https://blog.csdn.net/qq_38175040/article/details/105411407 今天开始正式抓包了 但过程却不是很顺 ...

  2. python修改excel内容

    前提:安装pip install xlutils和xlrd 思路:xlrd用来读数据,xlutils用来修改数据:先打开excel——读到原来的sheet页——生成可以修改的excel和sheet页— ...

  3. python中的n次方表示法 **n

    例题:计算2的n次方,n由用户输入(N次方用**表示)# n=eval(input('手动输入n的值:')) #个人感觉,不确定是int还是float时,用eval来表示,eval后面接表达式# pr ...

  4. Android实现二值点阵图识别

    好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star 前言 我这几天在做一个东西,就是一张像二维码这样的 n*n ...

  5. Gradle实战(01)--介绍与安装

    前言 本章你将学习到 Gradle的介绍 Gradle的安装 Gradle的hello world 1 Gradle的介绍 Gradle是专注于灵活性和性能的开源构建自动化工具 Gradle构建脚本是 ...

  6. 小白的springboot之路(十八)、i18n多语言支持(后端篇)

    0-前言 在有些系统中,比如网站,往往需要支持多国语言,英文版中文版什么的,这个其实也不难: 今天我们就来介绍spring boot中用i18n在后端支持多语言: 当然,也可以直接在前端用i18n直接 ...

  7. 重磅来袭 Vue 3.0 One Piece 正式发布

    代号为One Piece 的Vue3.0 在9月19日凌晨正式发布!! 此次vue3.0 为用户提供了全新的 composition-api 以及更小的包大小,和更好的 TypeScript 支持. ...

  8. 关于bat脚本中的命令状态码相关的%errorlevel%变量

    bat脚本中常用%errorlevel%表达上一条命令的返回值,即命令执行状态码.也称命令退出码 一般上一条命令的执行结果返回的值只有两种,0和非0 (如常见的1,2,4,5,9009等等),0一般会 ...

  9. java调用matlab生成exe文件

    一.Matlab生成Java Package 1.在MATLAB的Command Window输入deploytool命令,选择Library Compiler. 2.在弹出的窗口选择Java Pac ...

  10. node核心模块-vm

    vm vm是node的一个核心模块,核心功能官方文档介绍是: The vm module provides APIs for compiling and running code within V8 ...