• Go channel被关闭时的广播机制,以及遍历未关闭channel时会导致死锁阻塞问题


    Go channel特性

    • Go channel的广播机制
      当一个channel被 close时,所有通过select监听这个channel IO事件的goroutine,都会收到相关事件:当前监听的channel已关闭。
    func main() {
    	ch := make(chan int, 2)
    	for i := 1; i <= 2; i++ {
    		ch <- i
    	}
    
    	close(ch) // 关闭channel,v1、v2、v3都会收到相关事件
    
    	// Go channel的广播机制:三个select都监听到了相关事件
    	select {
    	case v1 := <-ch:
    		fmt.Println("v1: ", v1) // 输出:1
    	}
    
    	select {
    	case v2 := <-ch:
    		fmt.Println("v2: ", v2) // 输出:2
    	}
    
    	select {
    	case v3 := <-ch:
    		fmt.Println("v3: ", v3) // 输出:0,channel读完为空时,后续读出值为对应类型的零值
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 遍历未关闭的channel时会导致死锁阻塞:
      如果不close掉channel直接range遍历是会发生死锁的,原因是 当for循环读完channel的10个值之后会继续尝试读取下一个,而由于channel为空又没关闭,会一直阻塞形成死锁
    func main() {
    	ch := make(chan int, 10)
    	for i := 1; i <= 10; i++ {
    		ch <- i
    	}
    
    	// 遍历时,如果channel没有关闭,则会出现deadlock错误
    	// close(ch) // 注释掉,不关闭
    
    	// channel遍历
    	fmt.Println("start...")
    
    	for v := range ch {
    		fmt.Println("v: ", v) // 输出1、2后就会阻塞
    	}
    
    	fmt.Println("end...")
    }
    
    /* 
    仅输出:
    start...
    v:  1
    v:  2
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • close后的channel仍然可读,先读出接收到的有效数据,直至channel数据读完后,后续都会读到对应类型的零值,比如:int对应数值0string对应空字符串
    • 但是如果通过range读取,channel关闭后会直接跳出for循环: 通过i, ok := <-c中的ok为true还是false,来查看channel的状态,判断值是否有效。
  • 相关阅读:
    Python GRPC 10min掌握使用
    微信小程序 ssm图书馆付费自习室系统
    c++11产生指定范围内均匀分布随机数、产生大量不重复随机数
    python正则+多线程(代理)+线程池+协程
    网络安全之WebShell截获
    web前端Vue 报错:Uncaught (in promise) TypeError: Cannot read properties of nu
    什么是去中心化云计算?
    C语言创建txt并循环写进字符
    MySQL(4)
    FH511+TP4333组成一个户外移动电源照明野营灯方案。
  • 原文地址:https://blog.csdn.net/qq_37102984/article/details/128152775