0

0

安全关闭多 Goroutine 发送数据的 Channel

碧海醫心

碧海醫心

发布时间:2025-10-05 13:23:16

|

779人浏览过

|

来源于php中文网

原创

安全关闭多 goroutine 发送数据的 channel

并发编程中,Channel 是一种常用的 Goroutine 间通信方式。当多个 Goroutine 向同一个 Channel 发送数据时,如何安全地关闭该 Channel是一个常见的问题。如果在某个 Goroutine 中直接关闭 Channel,可能会导致其他 Goroutine 尝试向已关闭的 Channel 发送数据,从而引发 panic。本文将介绍一种使用 sync.WaitGroup 来安全关闭 Channel 的方法。

sync.WaitGroup 用于等待一组 Goroutine 完成。它可以跟踪一组 Goroutine 的完成情况,并在所有 Goroutine 完成后发出信号。我们可以利用 sync.WaitGroup 来确保在所有 Goroutine 都完成发送后,再关闭 Channel。

以下是一个使用 sync.WaitGroup 安全关闭 Channel 的示例:

package main

import (
    "fmt"
    "sync"
)

const WorkerCount = 10

func main() {
    // 一些输入数据用于操作。
    // 每个 worker 获得相同大小的份额来处理。
    data := make([]int, WorkerCount*10)

    for i := range data {
        data[i] = i
    }

    // 对所有条目求和。
    result := sum(data)

    fmt.Printf("Sum: %d\n", result)
}

// sum 通过将操作委托给并行处理输入数据子切片的 worker,将给定列表中的数字相加。
func sum(data []int) int {
    var sum int

    result := make(chan int)

    // 从 worker 累积结果。
    go func() {
        for value := range result {
            sum += value
        }
    }()

    // WaitGroup 将跟踪所有 worker 的完成情况。
    wg := new(sync.WaitGroup)
    wg.Add(WorkerCount)

    // 将工作分配到 worker 的数量上。
    chunkSize := len(data) / WorkerCount

    // 启动 worker。
    for i := 0; i < WorkerCount; i++ {
        go func(i int) {
            offset := i * chunkSize

            worker(result, data[offset:offset+chunkSize])
            wg.Done()
        }(i)
    }

    // 等待所有 worker 完成,然后返回结果。
    wg.Wait()
    close(result) // 安全关闭 Channel

    return sum
}

// worker 对给定列表中的数字求和。
func worker(result chan int, data []int) {
    var sum int

    for _, v := range data {
        sum += v
    }

    result <- sum
}

代码解释:

  1. sync.WaitGroup 的使用:

    卓敏淘宝客站群系统
    卓敏淘宝客站群系统

    卓敏淘宝客站群系统是卓敏工作室针对淘宝客开发的专业站群系统,经过三个月来的运作,目前已经超过两万个站点使用,未出现过任何漏洞,安全可靠。 卓敏淘宝客站群系统以快速建站、便捷管理、高效收益为特色,只需几分钟,即可完成您的一个淘宝客站点,免更新、免维护是卓敏淘宝客站群系统的又一大亮点,所有产品数据都根据用户后台设置的行业分类及关键词提出佣金最高、销售最多的产品,您不需要在淘宝开放平台上烦琐的申请AP

    下载
    • wg := new(sync.WaitGroup) 创建一个新的 sync.WaitGroup 实例。
    • wg.Add(WorkerCount) 设置等待的 Goroutine 数量。
    • wg.Done() 在每个 worker Goroutine 完成时调用,表示一个 Goroutine 完成。
    • wg.Wait() 阻塞当前 Goroutine,直到所有等待的 Goroutine 都调用了 wg.Done()。
  2. Channel 的安全关闭:

    • close(result) 在 wg.Wait() 之后调用,确保所有 worker Goroutine 都已完成发送操作,才关闭 Channel。
    • 使用 for value := range result 来接收channel数据,当channel关闭后会自动退出循环,避免死锁。

注意事项:

  • 确保在所有 Goroutine 完成发送后,才关闭 Channel。
  • 使用 sync.WaitGroup 可以有效地跟踪 Goroutine 的完成情况,从而安全地关闭 Channel。
  • 使用 for...range 结构来读取channel数据,可以避免读取已经关闭的channel。

总结:

使用 sync.WaitGroup 是一种安全可靠地关闭多 Goroutine 发送数据的 Channel 的方法。通过跟踪 Goroutine 的完成情况,我们可以确保在所有 Goroutine 完成发送后,才关闭 Channel,避免向已关闭的 Channel 发送数据导致的 panic。 这种模式在并发编程中非常有用,特别是在需要并行处理数据并将结果发送到单个 Channel 的场景中。

相关专题

更多
Golang channel原理
Golang channel原理

本专题整合了Golang channel通信相关介绍,阅读专题下面的文章了解更多详细内容。

247

2025.11.14

golang channel相关教程
golang channel相关教程

本专题整合了golang处理channel相关教程,阅读专题下面的文章了解更多详细内容。

342

2025.11.17

Golang 性能分析与pprof调优实战
Golang 性能分析与pprof调优实战

本专题系统讲解 Golang 应用的性能分析与调优方法,重点覆盖 pprof 的使用方式,包括 CPU、内存、阻塞与 goroutine 分析,火焰图解读,常见性能瓶颈定位思路,以及在真实项目中进行针对性优化的实践技巧。通过案例讲解,帮助开发者掌握 用数据驱动的方式持续提升 Go 程序性能与稳定性。

9

2026.01.22

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

56

2026.01.21

三角洲入口地址合集
三角洲入口地址合集

本专题整合了三角洲入口地址合集,阅读专题下面的文章了解更多详细内容。

50

2026.01.21

AO3中文版入口地址大全
AO3中文版入口地址大全

本专题整合了AO3中文版入口地址大全,阅读专题下面的的文章了解更多详细内容。

396

2026.01.21

妖精漫画入口地址合集
妖精漫画入口地址合集

本专题整合了妖精漫画入口地址合集,阅读专题下面的文章了解更多详细内容。

118

2026.01.21

java版本选择建议
java版本选择建议

本专题整合了java版本相关合集,阅读专题下面的文章了解更多详细内容。

3

2026.01.21

Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

16

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 4万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号