首页 >后端开发 >Golang >如何安全地关闭 Go 中未知长度的通道?

如何安全地关闭 Go 中未知长度的通道?

Patricia Arquette
Patricia Arquette原创
2024-12-23 17:44:14440浏览

How to Safely Close a Channel of Unknown Length in Go?

关闭未知长度的 Channel

在提供的代码中,出现错误“在关闭的通道上发送”,因为多个 goroutine 尝试发送已关闭通道上的值。这个问题是由于 Goroutine 之间缺乏同步造成的,因为一个 Goroutine 关闭了通道,而其他 Goroutine 仍在发送数据。

为了在这种情况下有效地关闭通道,必须确定所有发送者 Goroutine 何时关闭通道完成了他们的任务。这可以通过使用sync.WaitGroup来检测所有发送者协程何时完成发送值来实现。

这是使用sync.WaitGroup的修改后的代码:

func gen(ch chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    var i int
    for {
        time.Sleep(time.Millisecond * 10)
        ch <- i
        i++
        // when no more data (e.g. from db, or event stream)
        if i > 100 {
            break
        }
    }
}

func receiver(ch chan int) {
    for i := range ch {
        fmt.Println("received:", i)
    }
}

func main() {
    ch := make(chan int)
    wg := &sync.WaitGroup{}

    for i := 0; i < 10; i++ {
        wg.Add(1)
        go gen(ch, wg)
    }

    go func() {
        wg.Wait()
        close(ch)
    }()

    receiver(ch)
}

在此解决方案中,每个发送者 goroutine 都会向sync.WaitGroup 添加 1,以指示它将在通道上发送值。 close() goroutine 中的 wg.Wait() 确保只有在所有发送者 goroutine 完成其任务后才关闭通道,从而防止“在关闭的通道上发送”错误。

以上是如何安全地关闭 Go 中未知长度的通道?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn