为什么它不能交替打印价值
why it could not print value alternatively
我写了一个退出和同步队列通道
预期打印如下,但没有发生,
g1 或 g2 将连续两个打印值
我知道无缓冲通道同步规则,但我好像误解了它
g1 0
g2 1
g1 1
g2 1
g1 2
g2 2
go playground print alternatively code snippet
package main
import (
"fmt"
)
func main() {
exit := make(chan struct{})
transfer := make(chan int)
go func() {
defer func() {
close(exit)
}()
for i := 0; i < 20; i++ {
transfer <- i
fmt.Println("g1\t", i) // 1
}
}()
go func() {
for i := 0; i < 20; i++ {
<-transfer
fmt.Println("g2\t", i) // 3 4
}
}()
<-exit
}
因此,当您使用无缓冲通道时,它是一个阻塞事务;发生的情况是两个 go 例程都在某个点停止并且需要进行事务处理;一旦交易发生;两个 go routines 现在都可以向前移动,调度程序需要决定哪个 go routine 首先 运行 g1 和 g2 不是 100% 的机会以相同的顺序打印。
那是因为这里有数据提升。
你不能确定之后
transfer <- i
和 fmt.Println("g1\t", i) // 1
之前不应有上下文切换到另一个例程。
所以如果你希望它是原子的,你应该在这里添加另一个同步机制
我写了一个退出和同步队列通道
预期打印如下,但没有发生, g1 或 g2 将连续两个打印值 我知道无缓冲通道同步规则,但我好像误解了它
g1 0
g2 1
g1 1
g2 1
g1 2
g2 2
go playground print alternatively code snippet
package main
import (
"fmt"
)
func main() {
exit := make(chan struct{})
transfer := make(chan int)
go func() {
defer func() {
close(exit)
}()
for i := 0; i < 20; i++ {
transfer <- i
fmt.Println("g1\t", i) // 1
}
}()
go func() {
for i := 0; i < 20; i++ {
<-transfer
fmt.Println("g2\t", i) // 3 4
}
}()
<-exit
}
因此,当您使用无缓冲通道时,它是一个阻塞事务;发生的情况是两个 go 例程都在某个点停止并且需要进行事务处理;一旦交易发生;两个 go routines 现在都可以向前移动,调度程序需要决定哪个 go routine 首先 运行 g1 和 g2 不是 100% 的机会以相同的顺序打印。
那是因为这里有数据提升。
你不能确定之后
transfer <- i
和 fmt.Println("g1\t", i) // 1
之前不应有上下文切换到另一个例程。
所以如果你希望它是原子的,你应该在这里添加另一个同步机制