• 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)
    }
    
  • 相关阅读:
    ExquisiteWnd
    GDIPlusEncapsulation
    COleDateTimeSpan
    Create Win32 Window
    vagrant 安装配置,PhpStorm10 设置远程调试
    PHPExcel导出主要代码记录
    常用js方法集合,动态加载js方法--判断变量是否为空--截取小数点后几位--截取带中文的字条串
    最近遇到的各种坑
    控制台运行bee run project 报[ERRO] Fail to watch directory[too many open files]
    Mac 安装beego And bee工具
  • 原文地址:https://www.cnblogs.com/wangha/p/11421580.html
Copyright © 2020-2023  润新知