首页 >后端开发 >Golang >为什么关闭的Go Channel还能收到值?

为什么关闭的Go Channel还能收到值?

DDD
DDD原创
2024-12-09 17:42:12417浏览

Why Can I Still Receive Values from a Closed Go Channel?

为什么可以从封闭的 Channel 接收值

在 Go 中,channel 提供了 goroutine 之间的通信机制。当通道关闭时,表示不再发送任何值。但是,这并不意味着通道缓冲区中的现有值会立即被丢弃。

规范规定,关闭通道后,在收到零值之前仍然可以接收任何先前发送的值。这是因为通道的缓冲区充当队列,存储关闭操作之前发送的值。

工作原理:

考虑以下代码:

package main

import "fmt"
import "sync"
import "time"

func main() {
    iCh := make(chan int, 99)
    var wg sync.WaitGroup
    go func() {
        for i := 0; i < 5; i++ {
            wg.Add(1)
            go func(i int) {
                defer wg.Done()
                iCh <- i
            }(i)
        }
        wg.Wait()
        close(iCh)
    }()
    time.Sleep(5 * time.Second)
    for i := range iCh {
        fmt.Printf("%v\n", i)
    }
}

输出:

0
1
2
3
4

即使通道在之后关闭5秒后,for循环仍然收到关闭操作之前发送的5个值。这是因为通道缓冲区会存储这些值直到它们被消耗。

只有在接收到所有先前发送的值后,for 循环才会返回零值,表示通道已关闭。

为什么“Time.Sleep”技巧失败:

“time.Sleep”技巧并不能阻止goroutine 在通道关闭之前继续向通道发送值。当 goroutine 休眠 5 秒时,它们可能会发送额外的值,这些值仍会被 for 循环缓冲和接收。

以上是为什么关闭的Go Channel还能收到值?的详细内容。更多信息请关注PHP中文网其他相关文章!

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