我正在调查频道的行为,他们的行为让我很困惑。规范说,After calling close, and after any previously sent values have been received, receive operations will return the zero value for the channel's type without blocking.但是,即使到那个时候通道关闭了,我似乎仍然能在range语句中得到这些值。这是为什么?
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)
print("the channel should be closed by now\n")
for i := range iCh {
fmt.Printf("%v\n", i)
}
print("done")
}
Run Code Online (Sandbox Code Playgroud)
编辑:看来,如果我将close语句移动到通道范围之前,它将永久关闭它。因此,我想知道为什么它也不能与“ time.Sleep”技巧一起使用。到那时(5秒),所有执行例程都应该已经完成,并且通道已关闭,不是吗?
对于通道c,内置函数close(c)记录该通道将不再发送任何值。在调用close之后,并且在接收到任何先前发送的值之后,接收操作将返回通道类型的零值而不会阻塞。
在通道缓冲区中,有5个先前发送的值,后跟一个close。
例如,
package main
import (
"fmt"
"sync"
"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)
fmt.Println("previously sent values", len(iCh))
for i := range iCh {
fmt.Printf("%v\n", i)
}
print("the channel should be closed by now\n")
print("done")
}
Run Code Online (Sandbox Code Playgroud)
输出:
previously sent values 5
0
1
2
3
4
the channel should be closed by now
done
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1362 次 |
| 最近记录: |