首页 > 其他分享 >Golang chan 的实现原理

Golang chan 的实现原理

时间:2023-10-10 15:44:23浏览次数:38  
标签:wg chan sync Golang func 原理 main 通道

Golang chan 的实现原理

Go语言中的chan(通道)是一种用于在不同的goroutines之间进行通信和同步的重要机制。chan的实现原理涉及到Go语言的运行时系统和底层的数据结构。以下是chan的主要实现原理:

  1. 底层数据结构chan的底层数据结构是一个用于存储数据的环形队列(circular queue)或链表(linked list)。这个队列存储了被发送到通道的值,并且它可以有一个缓冲区,允许在发送和接收之间有一定的延迟。

  2. 并发安全性chan是并发安全的,可以被多个goroutine同时读取和写入而不需要额外的锁。这是因为Go运行时系统在底层处理了chan的同步和互斥。

  3. 操作的原子性chan的操作是原子的,这意味着在一个goroutine发送数据到通道时,它会等待直到数据被放入通道并且通道可用,然后才继续执行。类似地,一个goroutine接收数据时也会等待直到通道中有数据可用,然后再继续执行。

  4. 阻塞和非阻塞操作chan的发送和接收操作可以是阻塞的或非阻塞的,取决于通道的状态和缓冲区的容量。当通道已满时,发送操作会阻塞,直到有空间可用。当通道为空时,接收操作会阻塞,直到有数据可用。通过使用select语句,你可以实现非阻塞的通道操作。

  5. 关闭通道chan可以被关闭,以通知接收方不再有数据发送到通道中。关闭通道后,再次尝试发送数据到通道会引发panic。接收方可以使用特殊的接收语法来检查通道是否被关闭,并且在通道被关闭后,继续从通道中接收数据不会引发阻塞,而是会立即返回零值。

  6. 垃圾回收:Go运行时系统负责管理不再使用的chan的内存,以防止内存泄漏。

chan是Go语言中用于实现并发通信的重要机制,它的底层实现涉及到数据结构和运行时系统的协作,以提供安全且高效的并发通信功能。在Go中,chan是非常有用的工具,用于协调不同goroutines之间的工作。

使用场景

  1. 并发控制chan可以用于控制多个goroutines的执行顺序,例如等待所有goroutines完成后再继续执行。

    package main
    
    import (
        "fmt"
        "sync"
    )
    
    func main() {
        var wg sync.WaitGroup
        ch := make(chan int)
    
        for i := 0; i < 5; i++ {
            wg.Add(1)
            go func(i int) {
                defer wg.Done()
                // 做一些工作
                ch <- i
            }(i)
        }
    
        go func() {
            wg.Wait()
            close(ch)
        }()
    
        for num := range ch {
            fmt.Println("Received:", num)
        }
    }
    
  2. 数据传输chan用于在goroutines之间传递数据,可以用于生产者-消费者模型等场景。

    package main
    
    import (
        "fmt"
        "sync"
    )
    
    func main() {
        var wg sync.WaitGroup
        ch := make(chan int)
    
        // 生产者
        wg.Add(1)
        go func() {
            defer wg.Done()
            for i := 0; i < 5; i++ {
                ch <- i
            }
            close(ch)
        }()
    
        // 消费者
        wg.Add(1)
        go func() {
            defer wg.Done()
            for num := range ch {
                fmt.Println("Received:", num)
            }
        }()
    
        wg.Wait()
    }
    
  3. 信号通知chan可以用于在不同goroutines之间发送信号或通知,以触发某些操作。

    package main
    
    import (
        "fmt"
        "sync"
    )
    
    func main() {
        var wg sync.WaitGroup
        ch := make(chan struct{})
    
        // 启动一个goroutine等待通知
        wg.Add(1)
        go func() {
            defer wg.Done()
            fmt.Println("Waiting for notification...")
            <-ch // 阻塞等待通知
            fmt.Println("Received notification!")
        }()
    
        // 发送通知
        fmt.Println("Sending notification...")
        ch <- struct{}{}
    
        wg.Wait()
    }
    
  4. 限流chan可以用于限制并发执行的数量,以控制资源的使用。

    package main
    
    import (
        "fmt"
        "sync"
    )
    
    func main() {
        var wg sync.WaitGroup
        ch := make(chan struct{}, 2) // 限制最多两个并发
    
        for i := 0; i < 5; i++ {
            wg.Add(1)
            go func(i int) {
                defer wg.Done()
                ch <- struct{}{} // 发送信号占用一个通道
                defer func() {
                    <-ch // 释放通道
                }()
                // 执行一些工作
                fmt.Println("Processing task", i)
            }(i)
        }
    
        wg.Wait()
    }
    

这些是一些chan的常见使用场景和相应的示例。chan是Go语言中非常强大的工具,可以用于处理各种并发和通信需求。

标签:wg,chan,sync,Golang,func,原理,main,通道
From: https://www.cnblogs.com/sening/p/17754842.html

相关文章

  • golang map/sync.map 实现
    mapGo中的map是一种高效的散列表(hashtable)实现,它的底层实现细节包括以下重要方面:哈希表(HashTable):map的底层数据结构是一个哈希表。哈希表是一个数组,每个元素都是一个哈希桶,用于存储键值对。哈希函数(HashFunction):Go使用哈希函数将键映射到哈希桶。这个哈希函数是内......
  • CSRF 攻击原理与防御
    定义跨站请求伪造,攻击者利用服务器对用户信任,从而欺骗受害者点击vps上的恶意请求链接。与xss的区别xss是利用用户对服务端的信任;csrf利用服务端对用户的信任xss攻击是让脚本在用户浏览器上执行,服务端只是恶意脚本的载体;csrf攻击不需要知道用户cookie,让受害者点击我们准备......
  • 【Python&语义分割】语义分割的原理及常见模型的介绍
    1概述        语义分割是计算机视觉中的重要任务之一,其目的是将图像中的每个像素分配给特定的类别,从而实现对图像的精细分割。与目标检测不同,语义分割并不需要对物体进行位置和边界框的检测,而是更加注重对图像中每个像素的分类。随着深度学习的兴起,语义分割得到了广泛......
  • BOSHIDA DC电源模块电容滤波器的原理及构成
    BOSHIDADC电源模块电容滤波器的原理及构成DC电源模块电容滤波器是电源输出端的重要组成部分,其主要作用是滤除由电源输出的直流电压中所含的杂波和噪声,并将其平滑处理为一个稳定的直流电压输出。在电子设备的数字、模拟电路、电机驱动等方面,稳定的电源输出对于保证设备的正常运行......
  • 【Python&目标识别】目标检测的原理及常见模型的介绍
    1概述        目标检测(ObjectDetection)是计算机视觉领域的一个重要研究方向,其目的是在图像或视频中定位并识别出特定的物体。目标检测模型通常需要同时确定物体的位置和类别。在深度学习之前,目标检测算法主要基于传统计算机视觉方法,如特征提取和分类器设计。然而,随着深......
  • Django RestFramework、Celery及Channels
    DjangoRESTFramework什么是RESTfulAPIRESTfulAPI是一种基于HTTP协议的接口设计风格,它使用统一的接口和资源的概念来定义和操作网络应用程序的功能和数据。RESTfulAPI使用HTTP动词(GET、POST、PUT、DELETE等)来表示操作类型,并使用URL来标识资源。传统风格的HTTP接口常用授......
  • 解决 golang 中 grep console 插件不生效问题
    日志多了以后不好找,idea中的神奇grepconsole在goland竟然不好使了,一番查找下,找到了一个解决方案cmd+shift+a找到Registry找到go.run.processes.with.pty,改为false大功告成原贴:https://github.com/krasa/GrepConsole/issues/175......
  • channel 通道错误的使用例子
    1.向已经关闭的通道发送值,引起panic错误packagemainimport"fmt"funcrecv(cchanint){ ret:=<-c fmt.Println("接收成功",ret)}funcmain(){ ch:=make(chanint) gorecv(ch)//启用goroutine从通道接收值 ch<-10 close(ch) ch<-9 fmt.Prin......
  • 分布式锁-实现原理(setnx,redisson)
         ......
  • 音视频处理三剑客之 AEC:回声产生原因及回声消除原理
     在上一期课程《音视频开发者进阶——音频要素》中,我们从声音三要素、音频模拟信号的数字化和音频数字信号特征等方面,重新认识了“声音”这个老朋友。今天,我们会进一步聊聊这个老朋友在RTC世界中的其他故事。磨刀不误砍柴工,在主题开始之前,我们先来了解一下RTC场景中音视频数......