fatal error: all goroutines are asleep - deadlock!
一、问题截图
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
/Users/dianjiu/Codes/go/src/go-learn/demo03/demo.go:36 +0x164
goroutine 18 [chan receive]:
main.consumer(0x140001020c0, 0x14000102060)
/Users/dianjiu/Codes/go/src/go-learn/demo03/demo.go:10 +0x148
created by main.main
/Users/dianjiu/Codes/go/src/go-learn/demo03/demo.go:31 +0x104
exit status 2
[Done] exited with code=1 in 10.226 seconds
二、问题代码
package main
import (
"fmt"
"strconv"
"time"
)
func consumer(data chan int, done chan bool) {
for x := range data {
// println("recv:", x)
i := strconv.Itoa(x)
fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "调用客户端"+i+"结束")
// <-data
}
done <- true
}
func producer(data chan int, done chan bool, i, len int) {
x := strconv.Itoa(i)
fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "调用客户端"+x+"开始")
//单个客户端处理时间为10秒
time.Sleep(time.Second * 10)
data <- i
}
func main() {
fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "开始了")
done := make(chan bool)
data := make(chan int)
go consumer(data, done)
for i := 0; i < 5; i++ {
go producer(data, done, i, 5)
}
<-done
}
三、问题原因
出现上面协程死锁的原因是生产方法只会在data channel中放五个数据,消费方法在消费完这五个数据后,还会一直等待data channel有新的数据输入,无法结束。这样的话 Go就会判定为死锁。
四、问题解决
为了解决这个问题,我们在生产完五个数据后对data channel进行关闭,这样消费方法就可以正常退出了。
五、具体实现
利用sync.WaitGroup解决,在所有的 data channel 的输入处理之前,wg.Wait()这个goroutine会处于等待状态。当生产方法处理完后(wg.Done),wg.Wait()就会放开执行,执行后面的close(results)。
注意:要把wg.Add(1)放到go producer()外面。如果放到里面的话,(for i := 0; i < 5; i++)里的go producer()有可能会在wg.wait的go func之后执行,这样close(results)就会先执行。
package main
import (
"fmt"
"strconv"
"sync"
"time"
)
var wg sync.WaitGroup
func consumer(data chan int, done chan bool) {
for x := range data {
i := strconv.Itoa(x)
fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "调用客户端"+i+"结束")
}
done <- true
}
func producer(data chan int, done chan bool, i, len int) {
x := strconv.Itoa(i)
fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "调用客户端"+x+"开始")
//单个客户端处理时间为10秒
time.Sleep(time.Second * 10)
data <- i
defer wg.Done()
}
func main() {
fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "开始了")
done := make(chan bool)
data := make(chan int)
go func() {
wg.Wait()
close(data)
}()
go consumer(data, done)
for i := 0; i < 5; i++ {
wg.Add(1)
go producer(data, done, i, 5)
}
<-done
}
六、问题总结
所有 goroutine 在 main() 函数结束时会一同结束。

fatal error: all goroutines are asleep - deadlock!的更多相关文章
- golang fatal error: all goroutines are asleep - deadlock!
转自:https://www.cnblogs.com/ghj1976/p/4295013.html http://blog.csdn.net/skh2015java/article/details/6 ...
- 4.Android 打包时出现的Android Export aborted because fatal error were founds [closed]
Android 程序开发完成后,如果要发布到互联网上供别人使用,就需要将自己的程序打包成Android 安装包文件(Android Package,APK),其扩展名为.apk.使用run as 也能 ...
- PHP严重致命错误处理:php Fatal error: Cannot redeclare class or function
1.错误类型:PHP致命错误 Error type: PHP Fatal error Fatal error: Cannot redeclare (a) (previously declared in ...
- Slave I/O: Got fatal error 1236
[起因] 一次zabbix报警,从库[Warning] MySQL-repl was down # 不知道主库/storage空间小于20%时为什么没有触发trigger [从库错误日志] 1611 ...
- “fatal error C1010”错误解决的三种方法
尝试写了一个简单的类文件,但在编译的时候提示错误,具体错误信息如下: fatal error C1010: unexpected end of file while looking for preco ...
- "Fatal error: Call to undefined function: file_put_contents()"
打开页面时提示这个错误: Fatal error: Call to undefined function: file_put_contents() 意思是请求未定义的函数,出现这个提示通常有两种情况: ...
- fatal error
1. fatal error C1083: 无法打开源文件 编译报此错误: 1>c1xx : fatal error C1083: 无法打开源文件:“Projects\XXXCCCC\VB ...
- LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
同时安装了VS2012和VS2010,用VS2010 时 >LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 问题说明:当安装VS2012之后 ...
- (转)win7 64 安装mysql-python:_mysql.c(42) : fatal error C1083: Cannot open include file: 'config-win.h': No such file or directory
原文地址:http://www.cnblogs.com/fnng/p/4115607.html 作者:虫师 今天想在在win7 64位环境下使用python 操作mysql 在安装MySQL-pyth ...
随机推荐
- 二、部署监控服务器-Zabbix Server
二.部署监控服务器-Zabbix Server 1)源码安装Zabbix Server 多数源码包都是需要依赖包的,zabbix也- 样,源码编译前需要先安装相关依赖包. [root@zabbixse ...
- ES6中的新数据类型——Symbol
今天小编和大家来聊一聊es6中新增的一个原始数据类型Symbol.在es5中原始数据类型(基本数据类型)有以下六种:Undefind.Null.Bool. String.Number.Object.今 ...
- 复习Spring第四课---Spring对国际化的支持
其实国际化这东西很少使用,之前也就是粗略的学了下,趁今天有空,拿出来稍微写写.以前学android开发的时候,类似于多语言的版本.差别就是一个是手机打开,一个是浏览器打开,本质是一样的. 在Sprin ...
- 浅析uniapp
前端跨平台框架 之uniapp入门浅析 技术的发展总日新月异,处在风口,前端技术的发展尤为迅速,跨平台的概念也在前端流行起来.从最早期PhoneGap.lonic.Cordova,到近年来的Reac ...
- 低代码开发LCDP,Power Apps系列 - 新建泰勒创新中心门户案例
低代码简介 上世纪八十年代,美国就有一些公司和实验室开始了可视化编程的研究,做出了4GL"第四代编程语言",到后来衍生成VPL"Visual Programming La ...
- [HNOI2006]公路修建问题题解
题目 题目描述 OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那里的交通情况还是很糟糕.所以,OIER Association组织成立了, ...
- Python装饰器-给你的咖啡加点料
今天你的咖啡加糖了吗? 让我们通过一个简单的例子来引出装饰器的概念及用法.在引出装饰器之前,我们先来了解一下函数的概念. 一.函数回顾 1.在python中函数是一等公民,函数也是对象.我们可以把函数 ...
- CentOS-GitLab迁移(yum至Docker)
yum备份迁移Docker版的GitLab 注:确保版本一致 1.yum备份 $ gitlab-rake gitlab:backup:create 2.执行完成后,在/var/opt/gitlab/b ...
- 1.3.8、通过RemoteAddr匹配
server: port: 8080 spring: application: name: gateway cloud: gateway: routes: - id: guo-system4 uri: ...
- MYSQL数据库数据拆分之分库分表总结 (转)
数据存储演进思路一:单库单表 单库单表是最常见的数据库设计,例如,有一张用户(user)表放在数据库db中,所有的用户都可以在db库中的user表中查到. 数据存储演进思路二:单库多表 随着用户数 ...