获取用于循环的大型缓冲通道块的 len
Getting len of large buffered channel blocks for loop
我遇到了一个奇怪的行为。我在玩缓冲通道,当使用大缓冲区时,整个程序执行会阻塞。在以下代码片段中:
package main
import (
"fmt"
)
func main() {
choke := make(chan string, 150000)
go func() {
for i := 0; i < 10000000; i++ {
choke <- string(i)
fmt.Println("i=", i)
}
}()
for {
//fmt.Println(len(choke))
if len(choke) >= 150000 {
fmt.Println("Full")
}
}
}
我的程序在 ~96000 次迭代时阻塞并且永远不会达到 "Full" 打印,除非我在评估它之前打印出 len(choke)
。这可能是由于 fmt.Println
提供的延迟,因为问题也可能是 "fixed" 添加一个小的 time.Sleep
。
有人可以解释这种行为的原因吗?
发生这种情况是因为您的 goroutine 从未执行过。在 goroutine 之外的 "for" 循环是一个紧密循环,没有任何阻塞操作,这意味着它占用了所有调度程序时间。因此,您创建的 goroutine 永远不会被安排执行。
它在你有 print 语句时起作用,因为这是一个阻塞操作 (I/O),它会导致 Go 调度程序切换到你创建的 goroutine。
我遇到了一个奇怪的行为。我在玩缓冲通道,当使用大缓冲区时,整个程序执行会阻塞。在以下代码片段中:
package main
import (
"fmt"
)
func main() {
choke := make(chan string, 150000)
go func() {
for i := 0; i < 10000000; i++ {
choke <- string(i)
fmt.Println("i=", i)
}
}()
for {
//fmt.Println(len(choke))
if len(choke) >= 150000 {
fmt.Println("Full")
}
}
}
我的程序在 ~96000 次迭代时阻塞并且永远不会达到 "Full" 打印,除非我在评估它之前打印出 len(choke)
。这可能是由于 fmt.Println
提供的延迟,因为问题也可能是 "fixed" 添加一个小的 time.Sleep
。
有人可以解释这种行为的原因吗?
发生这种情况是因为您的 goroutine 从未执行过。在 goroutine 之外的 "for" 循环是一个紧密循环,没有任何阻塞操作,这意味着它占用了所有调度程序时间。因此,您创建的 goroutine 永远不会被安排执行。
它在你有 print 语句时起作用,因为这是一个阻塞操作 (I/O),它会导致 Go 调度程序切换到你创建的 goroutine。