Goroutines的顺序运行

时间:2018-09-16 03:02:26

标签: 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

输出顺序对我来说似乎很有趣,但无法完全了解其内部发生了什么。

2 个答案:

答案 0 :(得分:3)

仅有同步的地方是通道操作。这些语句之外的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同步的内容很有趣。

答案 1 :(得分:1)

这是go例程进行通信的方式。您可以使用通道进行这种同步,也可以使用一些内存锁定机制来实现相同的目的。

如果您有兴趣阅读更多有关这些链接的结帐信息

  1. http://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part1.html
  2. https://rakyll.org/scheduler/
  3. https://docs.google.com/document/d/1yIAYmbvL3JxOKOjuCyon7JhW4cSv1wy5hC0ApeGMV9s/pub