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的状态,判断值是否有效。
目录
相关文章
|
5天前
|
Go 调度 开发者
探索Go语言中的并发模式:goroutine与channel
在本文中,我们将深入探讨Go语言中的核心并发特性——goroutine和channel。不同于传统的并发模型,Go语言的并发机制以其简洁性和高效性著称。本文将通过实际代码示例,展示如何利用goroutine实现轻量级的并发执行,以及如何通过channel安全地在goroutine之间传递数据。摘要部分将概述这些概念,并提示读者本文将提供哪些具体的技术洞见。
|
18天前
|
存储 算法 Java
Go语言的内存管理机制
【10月更文挑战第25天】Go语言的内存管理机制
21 2
|
28天前
|
安全 Go 调度
探索Go语言的并发之美:goroutine与channel
在这个快节奏的技术时代,Go语言以其简洁的语法和强大的并发能力脱颖而出。本文将带你深入Go语言的并发机制,探索goroutine的轻量级特性和channel的同步通信能力,让你在高并发场景下也能游刃有余。
|
1月前
|
存储 安全 Go
探索Go语言的并发模型:Goroutine与Channel
在Go语言的多核处理器时代,传统并发模型已无法满足高效、低延迟的需求。本文深入探讨Go语言的并发处理机制,包括Goroutine的轻量级线程模型和Channel的通信机制,揭示它们如何共同构建出高效、简洁的并发程序。
|
23天前
|
存储 Go 调度
深入理解Go语言的并发模型:goroutine与channel
在这个快速变化的技术世界中,Go语言以其简洁的并发模型脱颖而出。本文将带你穿越Go语言的并发世界,探索goroutine的轻量级特性和channel的同步机制。摘要部分,我们将用一段对话来揭示Go并发模型的魔力,而不是传统的介绍性文字。
|
29天前
|
安全 Go 调度
探索Go语言的并发模型:Goroutine与Channel的魔力
本文深入探讨了Go语言的并发模型,不仅解释了Goroutine的概念和特性,还详细讲解了Channel的用法和它们在并发编程中的重要性。通过实际代码示例,揭示了Go语言如何通过轻量级线程和通信机制来实现高效的并发处理。
|
1月前
|
安全 Go 调度
探索Go语言的并发之美:goroutine与channel的实践指南
在本文中,我们将深入探讨Go语言的并发机制,特别是goroutine和channel的使用。通过实际的代码示例,我们将展示如何利用这些工具来构建高效、可扩展的并发程序。我们将讨论goroutine的轻量级特性,channel的同步通信能力,以及它们如何共同简化并发编程的复杂性。
|
1月前
|
安全 Go 数据处理
掌握Go语言并发:从goroutine到channel
在Go语言的世界中,goroutine和channel是构建高效并发程序的基石。本文将带你一探Go语言并发机制的奥秘,从基础的goroutine创建到channel的同步通信,让你在并发编程的道路上更进一步。
|
3月前
|
存储 编译器 Go
|
3月前
|
消息中间件 Kafka Go
从Go channel中批量读取数据
从Go channel中批量读取数据