【发布时间】:2021-05-17 11:44:20
【问题描述】:
从 Go 中的通道读取时,我观察到它没有遵循发布功能和消费功能之间的完美同步。奇怪的是,如果这是 CPU 调度的一个怪癖,有时我会得到不同的结果。 main 中的消费者似乎一次消费了两个并打印出来。
考虑以下示例:
package main
import (
"fmt"
)
func squares(ch chan int) {
for i:=0; i<9; i++ {
val:= i*i;
fmt.Printf("created val %v \n", val);
ch <- i*i;
fmt.Printf("After posting val %v \n", val);
}
close(ch)
}
func main() {
c := make(chan int)
go squares(c)
for val := range c{
fmt.Println(val);
}
}
无论我在 Go Playground 上运行多少次,我都会看到以下输出。
created val 0
After posting val 0
created val 1
0
1
After posting val 1
created val 4
After posting val 4
created val 9
4
9
After posting val 9
created val 16
After posting val 16
created val 25
16
25
After posting val 25
created val 36
After posting val 36
created val 49
36
49
After posting val 49
created val 64
After posting val 64
64
我不应该期待吗,因为 go 会阻止 squares 方法,直到 main 打印它?
created val 0
0
After posting val 0
...
如果不是,那为什么?如果我想要像上面这样的完美同步,我应该怎么做?
【问题讨论】:
-
你有什么问题?
-
这个输出非常好。
-
同步发生在实际的通道操作上。打印语句不同步,它们仅在各自的 go 例程中的操作序列中排序。
-
如果我想要完美同步怎么办?
标签: go concurrency