go - Goroutines 的运行顺序

标签 go

我现在正在学习 Golang,并且在网上看到了一些有趣的教程。例如这个:https://golangbot.com/channels/

在这部分关于goroutines,有一个例子如下:

package main

import (
    "fmt"
)

func producer(chnl chan int) {
    for i := 0; i < 10; i++ {
        fmt.Println("debugging send...", i)
        chnl <- i
    }
    close(chnl)
}
func main() {
    ch := make(chan int)
    go producer(ch)
    for {
        v, ok := <-ch
        if ok == false {
            break
        }
        fmt.Println("Received ", v, ok)
    }
}

fmt.Println("debugging send...", i) 行是我为调试目的添加的。输出是:

debugging send... 0
debugging send... 1
Received  0 true
Received  1 true
debugging send... 2
debugging send... 3
Received  2 true
Received  3 true
debugging send... 4
debugging send... 5
Received  4 true
Received  5 true
debugging send... 6
debugging send... 7
Received  6 true
Received  7 true
debugging send... 8
debugging send... 9
Received  8 true
Received  9 true

输出顺序对我来说似乎很有趣,但不能完全理解幕后发生的事情。

最佳答案

唯一同步的地方是 channel 操作。在这些语句之外,goroutine 中的操作顺序之间不需要相关性。

多次运行你的程序,我得到了你大部分时间的输出,但有时我也会看到这样的东西:

debugging send... 0
debugging send... 1
Received  0 true
Received  1 true
debugging send... 2
debugging send... 3
Received  2 true
Received  3 true
debugging send... 4
debugging send... 5
Received  4 true
Received  5 true
debugging send... 6
debugging send... 7
Received  6 true
debugging send... 8
Received  7 true
Received  8 true
debugging send... 9
Received  9 true

尝试运行这个 Bash shell 脚本多次运行该程序并比较其输出:

#!/bin/bash

# c.go has your Go program
go run c.go > first.txt
cat first.txt

echo "======"
while :; do
    go run c.go > run.txt
    if ! diff -q run.txt first.txt; then
        break
    fi
done

cat run.txt

编辑:您可能会发现 https://golang.org/ref/mem阅读 Go 中的同步很有趣。

关于go - Goroutines 的运行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52350602/

相关文章:

casting - 是否支持显式原始类型转换?

go - 用于运行Golang代码以进行调试和运行的文件路径

http - 为 mux gorilla 返回 404 的路由

go - 从 viper 配置文件中删除键值对

go - 在 Go 中使用事务

go - 在 martini.Context 中获取请求 url

go - 如何通过 corev1.PodLogOptions 从所有容器中获取日志?

go - 需要帮助来理解 Go 语言中的垃圾收集

arrays - 如何在循环中使用golang的追加到数组中

go - go1.4中是否有必要放弃堆栈上太大的变量以避免堆栈复制?