goroutine的使用时常见错误

goroutine是Golang 的核心之一,在使用时,一般都要配合channel一起使用。

在使用时,经常会遇到一些错误,包括:

  1. 不输出
  2. 输出与希望输出不一致
  3. all goroutines are asleep - deadlock!

对于error1,举个例子

func main() {
for i := 0; i < 3; i++ {
go func() {
fmt.Printf("f1:%d\n", i)
}()
}
}

我们使用go func()创建了三个routine,但是发现没有输出。

原因:

3个routine刚被创建完成,进程就结束了

解决:

我在main进程中设置了res := <-a来等待三个routine分别发信号,只有发完信号,3个routine才能结束

func main() {
a := make(chan int)
for i := 0; i < 3; i++ {
go func() {
a <- i
}()
}
for {
res := <-a
fmt.Printf("f1:%d\n", res)
}
close(a)
}

到目前为止,输出问题解决了,但是此时我们发现error2和error3都出来了

对于error2

到目前为止,我们发现,我们的输出为

f1:3
f1:3
f1:3

并非我们希望输出的f1:0 f1:1 f1:2

原因:

3个routine先被创建了,创建完后,执行routine内的内容,即读取i,然而此时i已经等于3,因此,读取时全部为3

解决:

变成go func(j int) {}(i),利用闭包函数传参

func main() {
a := make(chan int)
for i := 0; i < 3; i++ {
go func(j int) {
a <- j
}(i)
}
for {
res := <-a
fmt.Printf("f1:%d\n", res)
}
close(a)
}

此时,我们发现已经解决了输出不正确的问题,但是此时all goroutines are asleep - deadlock!还在

对于error3

原因:3个routine都已经执行完毕,但是channel还在等待信号

解决方式:channel的send/receive数量对应即可

func main() {
a := make(chan int)
for i := 0; i < 3; i++ {
go func(j int) {
a <- j
}(i)
}
for i := 0; i < 3; i++ {
res := <-a
fmt.Printf("f1:%d\n", res)
}
close(a)
}

goroutine的使用与常见错误的更多相关文章

  1. GO 新开发者要注意的陷阱和常见错误

    转自:http://colobu.com/2015/09/07/gotchas-and-common-mistakes-in-go-golang/ 初级 开大括号不能放在单独的一行 未使用的变量 未使 ...

  2. Go的50度灰:Golang新开发者要注意的陷阱和常见错误(转)

    目录 [−] 初级 开大括号不能放在单独的一行 未使用的变量 未使用的Imports 简式的变量声明仅可以在函数内部使用 使用简式声明重复声明变量 偶然的变量隐藏Accidental Variable ...

  3. [转载]Go的50度灰:Golang新开发者要注意的陷阱和常见错误

    初级 开大括号不能放在单独的一行 未使用的变量 未使用的Imports 简式的变量声明仅可以在函数内部使用 使用简式声明重复声明变量 偶然的变量隐藏Accidental Variable Shadow ...

  4. Golang新开发者要注意的陷阱和常见错误

    转自:http://colobu.com/2015/09/07/gotchas-and-common-mistakes-in-go-golang/ 目录 [−] 初级 开大括号不能放在单独的一行 未使 ...

  5. 初识JAVA(二)(送给Java和安卓初学者)----常见错误

    博主接着上篇的来讲哦,以后的更新中,博主会出一些练习题,有兴趣的可以做做然后吧代码粘贴到下面,大家可以一起研究学习,一起进步,本篇文章主要讲的是: 一.常见错误 二.连接上篇一起的训练 无论是什么方向 ...

  6. ubuntu 常见错误--Could not get lock /var/lib/dpkg/lock

    ubuntu 常见错误--Could not get lock /var/lib/dpkg/lock 通过终端安装程序sudo apt-get install xxx时出错:E: Could not ...

  7. coreseek常见错误原因及解决方法

    coreseek常见错误原因及解决方法 Coreseek 中文全文检索引擎 Coreseek 是一款中文全文检索/搜索软件,以GPLv2许可协议开源发布,基于Sphinx研发并独立发布,专攻中文搜索和 ...

  8. Android Fragment使用(二) 嵌套Fragments (Nested Fragments) 的使用及常见错误

    嵌套Fragment的使用及常见错误 嵌套Fragments (Nested Fragments), 是在Fragment内部又添加Fragment. 使用时, 主要要依靠宿主Fragment的 ge ...

  9. C语言初学者代码中的常见错误与瑕疵(23)

    见:C语言初学者代码中的常见错误与瑕疵(23)

随机推荐

  1. git让线上代码强制覆盖本地的

    git强制覆盖本地命令(分步执行): git fetch --all    git reset --hard origin/master    git pull git强制覆盖本地命令(单条执行):  ...

  2. Linux安全学习

    安全游戏说明 游戏形式帮助初学者学习和实践网络安全,主要是Linux shell命令的练习. https://overthewire.org/wargames/ 二进制 灰帽黑客进阶秘籍之一--lin ...

  3. Github-Dorks与辅助工具

    前言 Github搜索功能非常强大且有用,可用于在开源出来的Github仓库中搜索敏感数据.可以找到敏感的个人和/或组织信息(例如私钥,凭据,身份验证令牌等). 文中的github dork列表可以在 ...

  4. kexue shangwang

    根据实践,pptp.IPsec甚至OpenVPN等kexue上网法已经无法顺利翻越GFW.通过抓包可知,GFW会将pptp的握手期间的ack包吞掉,导致本地一直无法收到服务器端的响应.而OpenVPN ...

  5. 【VS开发】MFC CListCtrl列表控件的消息响应

    MFC里的CListCtrl选中一行,消息是哪个.实在想不起来了.找了一篇文章,比较有用: http://www.cnblogs.com/hongfei/archive/2012/12/25/2832 ...

  6. 在使用FPGA来控制DDR3/DDR2 IP 的时候两个错误的解决办法

    对于熟悉Intel FPGA的老(gong)司(cheng)机(shi)来说,外部存储器的控制早已是轻车熟路,但是对于新手,DDR3/DDR2 的IP使用也许并没有那么简单,不过没关系,骏龙的培训网站 ...

  7. C# 编译器 和 反编译器,你要哪个(歪头)? 我全都要(捏拳)!

    前言 从 C# 6.0 开始,C# 编译器就从以前由 C++ 实现的 csc.exe 换成了用 C# 重新实现的开放式 API 式编译服务 Roslyn.这个编译器到现在已经替代了老式编译器,从前 W ...

  8. iptables 深度详解

    iptables 是 Linux 中比较底层的网络服务,它控制了 Linux 系统中的网络操作,在 CentOS 中的 firewalld 和 Ubuntu 中的 ufw 都是在 iptables 之 ...

  9. 【LeetCode】最长回文子串【动态规划或中心扩展】

    给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad"输出: "bab"注意: " ...

  10. Java基础笔试练习(八)

    1. 以下关于构造函数的描述错误的是 ( ) A.每个类有且只能有一个构造函数. B.构造函数是类的一种特殊函数,它的方法名必须与类名相同 C.构造函数的主要作用是完成对类的对象的初始化工作 D.一般 ...