Golangchannel信号传递与事件通知示例

使用struct{}作为零开销信号载体,主协程通过接收channel通知等待子任务完成;2. 多个goroutine通过fan-in模式向同一channel发送完成信号,实现统一事件通知。

golangchannel信号传递与事件通知示例

在Go语言中,channel不仅是数据传递的工具,也常用于信号传递与事件通知。这类场景下,我们并不关心传递的数据内容,而是在于“某个事件发生了”这一事实。下面通过几个典型示例说明如何使用channel实现事件通知机制。

1. 使用空结构体进行事件通知

由于struct{}不占用内存空间,常被用作纯粹的信号载体。

示例:主协程等待子协程完成任务

package main

import ("fmt""time")

func worker(done chan struct{}) {fmt.Println("工作开始...")time.Sleep(2 * time.Second) // 模拟耗时操作fmt.Println("工作完成")close(done) // 通过关闭channel发送完成信号}

func main() {done := make(chan struct{})

go worker(done)<-done // 阻塞等待,直到收到完成信号fmt.Println("接收到完成通知,主程序退出")

}

立即学习“go语言免费学习笔记(深入)”;

2. 多个事件的统一通知(fan-in模式)

多个goroutine完成各自任务后,向同一个channel发送信号,主协程统一接收。

func doTask(id int, ch chan<- struct{}) {    fmt.Printf("任务 %d 开始n", id)    time.Sleep(time.Duration(id) * time.Second)    fmt.Printf("任务 %d 完成n", id)    ch <- struct{}{}}

func main() {const numTasks = 3ch := make(chan struct{}, numTasks) // 缓冲channel避免阻塞发送

for i := 1; i <= numTasks; i++ {    go doTask(i, ch)}// 等待所有任务完成for i := 0; i < numTasks; i++ {    <-ch}fmt.Println("所有任务已完成")

}

立即学习“go语言免费学习笔记(深入)”;

3. 超时控制与取消通知

结合select和time.After实现带超时的事件等待。

func fetchData(ch chan string) {    time.Sleep(3 * time.Second)    ch <- "数据获取成功"}

func main() {result := make(chan string, 1)

go fetchData(result)select {case data := <-result:    fmt.Println(data)case <-time.After(2 * time.Second):    fmt.Println("请求超时")}

}

立即学习“go语言免费学习笔记(深入)”;

4. 使用context实现优雅取消

对于更复杂的场景,推荐使用context配合channel实现取消信号广播。

func worker(ctx context.Context) {    for {        select {        case <-ctx.Done():            fmt.Println("收到取消信号,退出工作")            return        default:            fmt.Print(".")            time.Sleep(500 * time.Millisecond)        }    }}

func main() {ctx, cancel := context.WithCancel(context.Background())go worker(ctx)

time.Sleep(3 * time.Second)cancel() // 发送取消通知time.Sleep(1 * time.Second) // 等待worker退出

}

立即学习“go语言免费学习笔记(深入)”;

基本上就这些常见模式。核心在于理解channel不仅可以传数据,还能表达“状态变化”或“时机同步”。选择close(channel)、发送空结构体还是结合context,取决于具体场景的复杂度和可维护性需求。不复杂但容易忽略的是缓冲大小和资源释放问题。

以上就是Golangchannel信号传递与事件通知示例的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1405113.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月15日 21:04:55
下一篇 2025年12月15日 21:05:12

相关推荐

  • Golangcontainer/heap实现堆数据结构示例

    答案:Go语言通过container/heap包提供堆操作,需实现heap.Interface并使用heap.Init、heap.Push等函数初始化和维护堆结构。 Go语言标准库中的container/heap包提供了一个堆(优先队列)的接口实现,但不直接提供完整的堆类型。你需要先实现heap.I…

    好文分享 2025年12月15日
    000
  • 在Go语言中访问Android API:演进与实践

    本文探讨了Go语言在Android平台访问原生API的历程与现状。最初,由于Android框架以Java为主且Go编译器限制,直接调用API困难重重。然而,随着golang.org/x/mobile包的出现,Go语言现在可以通过JNI实现与Java的绑定,并支持图形、音频和用户输入,主要应用于游戏开…

    2025年12月15日
    000
  • Golang常用模板引擎安装与使用方法

    &lt;blockquote&gt;Go语言中处理动态内容渲染主要依赖模板引擎,内置的html/template和text/template分别用于HTML和纯文本生成,前者具备自动HTML转义以防止XSS攻击,后者适用于配置文件、日志等非HTML场景;通过定义数据结构并绑定到模板,…

    好文分享 2025年12月15日
    000
  • 掌握Go语言结构体字段标签:语法、用途与反射实践

    Go语言的结构体字段可以附带一个可选的字符串字面量,称为字段标签(struct tag)。这些标签不被Go运行时直接使用,而是作为元数据,通过反射机制被外部库(如JSON编码、数据库ORM)读取和解析,用于控制序列化、数据映射、验证等行为,极大地增强了结构体的灵活性和表达能力。 什么是结构体字段标签…

    2025年12月15日
    000
  • go语言适合做什么项目?

    Go语言适合高并发、I/O密集型项目,如网络服务、微服务、命令行工具和DevOps自动化;其轻量级goroutine实现高效并发,静态编译生成无依赖单文件便于部署,标准库强大且跨平台支持优秀,尤其适用于需高性能与快速迭代的场景。 Go语言,在我看来,最适合那些需要高性能、高并发处理能力,同时又追求开…

    2025年12月15日
    000
  • Golang指针与map引用关系解析

    答案:Go中map是引用类型,本质是指向底层数据的指针封装,函数传参时传递的是指针副本,故能修改原内容但无法重新赋值原变量;需重新分配或判nil初始化时应使用*map,否则直接传map即可。 在Go语言中,指针和map的使用非常频繁,但它们之间的关系容易引起误解。很多人以为map是引用类型,传参时不…

    2025年12月15日
    000
  • Go语言切片深度解析:避免二维切片初始化中的“索引越界”错误

    在使用Go语言处理切片,特别是二维切片时,不正确的初始化方式是导致index out of range运行时错误的常见原因。本文将深入探讨make函数中长度与容量的关键区别,并通过实际案例演示如何正确初始化和操作二维切片,从而有效避免索引越界问题,确保程序稳定运行。 Go语言切片基础与make函数 …

    2025年12月15日
    000
  • Golang反射在Web框架中路由绑定应用

    Golang反射实现Web路由绑定的核心是通过运行时动态调用函数,利用reflect.TypeOf和reflect.ValueOf检查并调用处理函数,结合路由结构体存储路径与处理器,实现请求匹配与自动执行。 Golang反射在Web框架中的路由绑定,核心在于动态地将HTTP请求与特定的处理函数关联起…

    2025年12月15日
    000
  • Golang微服务与缓存系统集成实践

    Golang%ignore_a_1%集成缓存系统可显著提升性能与可伸缩性,核心是通过Redis等内存数据库减少数据库访问。采用Cache-Aside模式实现读写分离,读时先查缓存,未命中则回源数据库并回填,写时先更新数据库再删除缓存;结合JSON或Protobuf序列化结构体,利用连接池优化并发性能…

    2025年12月15日
    000
  • 解决gccgo编译Go 1代码的兼容性问题

    本文旨在解决使用旧版本gccgo编译Go 1代码时遇到的import file ‘math/rand’ not found错误。核心解决方案包括升级gccgo至4.7.1或更高版本以获得完整的Go 1兼容性,或在无法升级时,针对特定情况修改导入路径(如将math/rand改为…

    2025年12月15日
    000
  • Golang使用Protocol Buffers定义消息结构

    答案是Golang通过Protobuf实现高效、类型安全的序列化。首先编写.proto文件定义消息结构,如User包含id、name等字段;接着安装protoc编译器和Go插件,运行protoc命令生成Go代码;在Go应用中导入生成的包和protobuf库,即可创建、序列化和反序列化消息。相比JSO…

    2025年12月15日
    000
  • Golang使用Fyne快速搭建桌面应用

    Fyne是基于Go语言的跨平台桌面应用开发框架,支持Windows、macOS、Linux及移动端;通过go install fyne.io/fyne/v2/cmd/fyne@latest安装工具链后,可使用fyne new创建项目,编写代码时利用其提供的App、Window和Widget等组件构建…

    2025年12月15日
    000
  • Golang装饰器模式在HTTP中间件应用

    装饰器模式通过嵌套函数实现Golang HTTP中间件,允许在请求处理前后添加日志、认证等功能,提升代码复用性;利用context传递数据,控制执行顺序,并结合错误处理与接口抽象实现可测试的中间件。 装饰器模式在Golang HTTP中间件中的应用,简单来说,就是通过一层层包裹函数,在请求到达最终处…

    2025年12月15日
    000
  • Golang基准测试Benchmark函数使用技巧

    答案:Go基准测试需掌握b.N、b.ResetTimer、b.ReportAllocs等核心方法,合理使用b.RunParallel进行并发测试,并结合-benchmem、pprof等工具分析内存分配与性能瓶颈,确保测试环境稳定、数据可控,以获得准确、可重复的性能指标。 Golang的基准测试(Be…

    2025年12月15日
    000
  • gccgo编译Go 1代码:math/rand导入问题及解决方案

    本文针对使用旧版gccgo编译Go 1代码时出现的import file ‘math/rand’ not found错误,提供了详细的解决方案。核心方法包括升级gccgo至4.7.1或更高版本以支持Go 1规范,以及在特定简单情况下,通过修改导入路径math/rand为rand进行临时兼容。文章强调…

    2025年12月15日
    000
  • Golang实现简单计算器项目教程

    答案:用Golang实现命令行四则运算计算器,通过导入fmt包、定义main和calculate函数,实现用户输入两个数字及操作符后输出结果,支持加减乘除,包含除零判断和错误提示,适合初学者掌握基本语法、函数定义、条件判断与用户交互处理。 用Golang实现一个简单计算器,适合初学者练手。这个项目能…

    2025年12月15日
    000
  • Golang runtime库运行时信息获取与调优

    答案:通过runtime.MemStats和pprof工具分析内存、goroutine及GC数据,定位内存泄漏、并发瓶颈并优化。 在Go语言的世界里, runtime 库就像是应用的心电图和血常规报告,它提供了对程序内部运行状态的直接洞察。要获取这些信息并进行调优,核心在于理解 runtime 包以…

    2025年12月15日
    000
  • Go 语言中结构体字段共享与 JSON 映射:利用嵌入简化数据流转

    在 Go 语言中处理不同数据表示(如内部数据库模型与外部 API 接口)时,如果多个结构体拥有相同的 Go 字段名但可能需要不同的 JSON 标签,传统的字段复制或反射操作会增加复杂性。本教程将深入探讨 Go 语言的结构体嵌入(Struct Embedding)机制,展示如何通过这种优雅的方式实现结…

    2025年12月15日
    000
  • 如何解决不同Golang依赖模块间接引用了同一个库的不同版本问题

    答案是处理Go模块间接依赖版本冲突需遵循最小版本选择原则,先用go mod tidy清理依赖,再通过go mod graph分析依赖树定位冲突源头;若存在不兼容问题,可使用go mod edit -replace强制替换版本或在go.mod中显式声明间接依赖的兼容版本以解决冲突。 处理Go模块间接依…

    2025年12月15日
    000
  • Golang接口基础语法与实现方法

    Go接口通过隐式实现提供多态性,无需显式声明,只要类型实现接口所有方法即可。如Shape接口被Circle和Rectangle隐式实现,变量可动态持有不同实例,体现解耦与灵活性。接口设计应遵循小接口、面向调用者、组合等原则,避免过度抽象。空接口interface{}可存储任意类型,配合类型断言提取具…

    2025年12月15日
    000

发表回复

登录后才能评论
关注微信