zoukankan      html  css  js  c++  java
  • goroutine的使用与常见错误

    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
    ", 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
    ", 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
    ", 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
    ", res)
    	}
    	close(a)
    }
    
  • 相关阅读:
    Oracle数据库安装
    [转]卡西欧手表调日期正确方法
    python密码处理(可用于生产模式)
    [转]python对json的相关操作
    [转]Python中的with…as…
    Python标准库--os模块
    我的github代码添加
    Python正则表达式+自创口诀
    自己总结python用xlrdxlwt读写excel
    CentOS安装+配置+远程
  • 原文地址:https://www.cnblogs.com/wangha/p/11421580.html
Copyright © 2011-2022 走看看