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)
    }
    
  • 相关阅读:
    Binary Tree Level Order Traversal II
    图和图的遍历算法
    Remove Duplicates from Sorted List
    Binary Tree Preorder Traversal
    Merge Sorted Array
    [POJ2774][codevs3160]Long Long Message
    [BZOJ2251][2010Beijing Wc]外星联络
    [BZOJ1692][Usaco2007 Dec]队列变换
    [BZOJ1717][Usaco2006 Dec]Milk Patterns 产奶的模式
    [BZOJ1131][POI2008]Sta
  • 原文地址:https://www.cnblogs.com/wangha/p/11421580.html
Copyright © 2011-2022 走看看