不去例行公事,频道按通话顺序工作吗?

Doesn't go routine and the channels work in order of call?

不按常规进行,频道按调用顺序工作。

并在区域变量之间进行常规共享值?

main.go

var dataSendChannel = make(chan int)

func main() {
    a(dataSendChannel)
    time.Sleep(time.Second * 10)
    
}

func a(c chan<- int) {
    for i := 0; i < 1000; i++ {
        go b(dataSendChannel)
        c <- i
    }
}

func b(c <-chan int) {
    val := <-c
    fmt.Println(val)
}

输出

> go run main.go
0
1  
54 
3  
61 
5  
6  
7  
8  
9  

频道 已排序。 Goroutines 不是。只要逻辑上 允许 到 运行,Goroutine 可能会 运行 或停止,或多或少是随机的。他们 必须 在您强迫他们这样做时停止并等待,例如,通过尝试在完整通道上写入,或对已锁定的互斥体使用 mutex.Lock() 调用,或任何此类事情。

您的 dataSendChannel 是无缓冲的,因此写入它的尝试将暂停,直到某个 goroutine 主动尝试从中读取。函数 a 派生出一个 goroutine,该 goroutine 将尝试读取一次 (go b(...)),然后写入并因此等待至少一个 reader 读取。函数b立即开始​​读取,等待数据。这解除了函数 a 的阻塞,它现在可以写入一些整数值。函数 a 现在可以衍生出另一个 b 的实例,它开始读取;这可能发生在获得值的 b 开始调用 fmt.Println 之前、期间或之后。 b 的第二个实例现在必须等待某人——在本例中是 always 函数 a,运行 循环——发送另一个值,但 a 会尽快执行此操作。 b 的第二个实例现在可以开始调用 fmt.Println,但它可能(主要是随机的)还没有机会这样做。 b 的第一个实例可能已经在 fmt.Println 中,或者可能还没有,第二个实例可能 运行 第一个——或者可能 both 稍等片刻,b 第三个 实例启动,从通道中读取一些值,依此类推。

无法保证 b 的哪个 实例实际进入 fmt.Println ,因此您的值看到印刷品将以某种半随机顺序出现。如果您希望各种 b 实例自行排序,它们将需要以某种方式执行此操作。