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. 【mysql 默认密码】ubuntu 上 初次启动mysql 默认密码

    对于debian系的系统,mysql初始默认密码 cat /etc/mysql/debian.cnf

  2. C# 恢复工作空间,删除Unversioned文件,两种方式

    //通过命令行清理svn的工作空间,删除未add的文件,revert修改的文件 public static bool RevertDelUnversioned(string svnPath) { tr ...

  3. 有些新电脑采用“UEFI”作为固件。由于UEFI不支持DOS,所以在UEFI环境下安装的WIN10等系统也就无法使用基于DOS的一键GHOST

    有些新电脑采用“UEFI”作为固件.由于UEFI不支持DOS,所以在UEFI环境下安装的WIN10等系统也就无法使用基于DOS的一键GHOST

  4. Gevent模块,协程应用

    Gevent官网文档地址:http://www.gevent.org/contents.html 进程.线程.协程区分 我们通常所说的协程Coroutine其实是corporate routine的缩 ...

  5. Linux交换分区内存优化

    swappiness的值的大小对如何使用swap分区是有着很大的联系的.swappiness=0的时候表示最大限度使用物理内存,然后才是 swap空间,swappiness=100的时候表示积极的使用 ...

  6. Python: ImportRequestsError: No module named 'requests'解决方法

    运行Python程序时,出现下面错误: import requests  ModuleNotFoundError: No module named ‘requests’ 原因:没有导入requests ...

  7. python基础 — 局部变量/全局变量

    变量作用区域 变量器作用的额代码范围称为变量的作用与,不同作用区域之间互不影响,函数每部定义的变量一般为局部变量,而不属于任何函数的变量一般为全局变量.所以我们在这里按变量的作用区域分为两类,全局变量 ...

  8. 05- if-else语句、循环for

    if-else 语句 if是条件语句.if语句的语法是 if 条件{ #注意大括号和条件之间不能换行 执行代码 } if语句还包括else if 和 else 部分 package main impo ...

  9. 可能这些是你想要的H5软键盘兼容方案

    前言 最近一段时间在做 H5 聊天项目,踩过其中一大坑:输入框获取焦点,软键盘弹起,要求输入框吸附(或顶)在输入法框上.需求很明确,看似很简单,其实不然.从实验过一些机型上看,发现主要存在以下问题: ...

  10. Js学习04--对象

    1.如何辨别js中的对象 除了五种基本的数据类型,其他的都是对象.万物皆对象. 2.Js中对象的分类 1)内建对象 由ES标准定义的对象,在任何的ES实现中都可以使用. eg:String.Numbe ...