为什么它不能交替打印价值

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 <- ifmt.Println("g1\t", i) // 1 之前不应有上下文切换到另一个例程。

所以如果你希望它是原子的,你应该在这里添加另一个同步机制