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

简介: 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读完为空时,后续读值都为0值
    }
}
  • 遍历未关闭的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
*/
  • close后的channel仍然可读,先读出接收到的有效数据,直至channel数据读完后,后续都会读到对应类型的零值,比如:int对应数值0string对应空字符串 ...
  • 但是如果通过range读取,channel关闭后会直接跳出for循环: 通过i, ok := <-c中的ok为true还是false,来查看channel的状态,判断值是否有效。
目录
相关文章
|
1月前
|
缓存 负载均衡 Java
Go语言调度器机制详解
【2月更文挑战第16天】Go语言以其强大的并发编程能力而闻名,这背后离不开其高效的调度器机制。本文将对Go语言的调度器机制进行详细的解析,包括调度器的设计原理、核心组件、调度策略以及优化技巧等方面,帮助读者深入理解Go语言并发编程的底层原理,更好地发挥Go语言并发编程的优势。
|
2月前
|
Go 开发者
Go语言中的错误处理与异常机制:实践与最佳策略
【2月更文挑战第7天】Go语言以其独特的错误处理机制而闻名,它鼓励显式错误检查而不是依赖于异常。本文将探讨错误处理与异常机制在Go语言中的实际应用,并分享一些最佳实践,帮助开发者编写更加健壮和易于维护的Go代码。
|
3月前
|
缓存 Go API
Go 实现一个支持多种过期、淘汰机制的本地缓存的核心原理
本文旨在探讨实现一个支持多种 过期、淘汰 机制的 go 本地缓存的核心原理,我将重点讲解如何支持多样化的过期和淘汰策略。
73 0
|
4月前
|
存储 安全 Java
Go 基础数据结构的底层原理(slice,channel,map)
Go 基础数据结构的底层原理(slice,channel,map)
53 0
|
1月前
|
设计模式 缓存 安全
一篇文章带你吃透Go语言的Atomic和Channel--实战方法
一篇文章带你吃透Go语言的Atomic和Channel--实战方法
29 0
|
1月前
|
存储 Go
|
1月前
|
资源调度 监控 Go
|
1月前
|
安全 Go 开发者
Go语言中的反射机制深度解析
【2月更文挑战第19天】Go语言的反射机制提供了一种在运行时检查对象类型、获取和设置对象字段、调用对象方法的能力。本文通过深入解析Go语言反射机制的核心概念、使用方法和注意事项,帮助读者更好地理解和应用这一强大而灵活的工具。
|
2月前
|
Go 开发者
Go语言错误处理机制:原理与实践
【2月更文挑战第7天】在Go语言中,错误处理是一项核心特性。Go语言鼓励显式的错误检查,而不是依赖于异常机制。本文将深入探讨Go语言的错误处理机制,包括错误的表示、传播和处理方式,以及如何在日常编程中有效地应用这一机制,确保代码的健壮性和可读性。
34 10
|
3月前
|
Go
Go语言Channel进阶:巧妙运用超时机制
Go语言Channel进阶:巧妙运用超时机制
80 0