我现在正在学习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
输出顺序对我来说似乎很有趣,但无法完全了解其内部发生了什么。
答案 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例程进行通信的方式。您可以使用通道进行这种同步,也可以使用一些内存锁定机制来实现相同的目的。
如果您有兴趣阅读更多有关这些链接的结帐信息