Bul*_*ula 6 concurrency go goroutine
我正在关注Go Tour,当涉及到goroutines时我有点卡住了.我知道他们非常轻量级,每次goroutine阻止,另一个将开始,但我无法理解这个例子实际如何工作:
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(1000 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
Run Code Online (Sandbox Code Playgroud)
据我所知,一个goroutine是针对具有参数"world"的say函数启动的,但据我所知,应该打印"world"五次并且"hello"一次.但是我不明白为什么输出是这样的:
hello
world
hello
world
hello
world
hello
world
hello
Run Code Online (Sandbox Code Playgroud)
从我对其他语言的线程的有限理解,输出应该是这样的:
hello
world
world
world
world
world
Run Code Online (Sandbox Code Playgroud)
或者像这样:
world
world
world
hello
world
world
Run Code Online (Sandbox Code Playgroud)
为什么第二行也执行五次?go语句下面的任何内容都会归类为go例程的一部分吗?
下一张幻灯片还显示了我无法再次回头看的内容:
package main
import "fmt"
func sum(a []int, c chan int) {
sum := 0
for _, v := range a {
sum += v
}
c <- sum // send sum to c
}
func main() {
a := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(a[:len(a)/2], c)
go sum(a[len(a)/2:], c)
x, y := <-c, <-c // receive from c
fmt.Println(x, y, x+y)
}
Run Code Online (Sandbox Code Playgroud)
甲够程开始切片的后半部分,然后另外一个切片的第一部分,但是这些值x和y已被分配了两个不同的值.我看到它的方式sum函数会将它的总和发送到通道c,然后下一个sum将它的总和发送到同一个通道,c那么如何为两个变量分配两个不同的值?渠道不应该c只有一个单一的sum价值吗?
我很欣赏这是一个很长的问题,但我无法找到这些问题的答案.
为什么第二行也执行5次?
第二行将hello在main()线程中每隔5次打印一次.
但同时第一行go say("world")也会在一个单独的goroutine中每隔五秒打印一次世界.
在Sleep确保每个例程的产量,让对方恢复.
因此输出:
hello
world
hello
world
hello
world
hello
world
hello
Run Code Online (Sandbox Code Playgroud)
我看到它的方式sum函数会将它的总和发送到通道c,然后下一个和将它的总和发送到同一个通道c,那么如何为这两个变量分配两个不同的值?
因为每个发送都将阻塞,c直到c读取通道.
由于有两个写入c,您需要阅读:
x, y := <-c, <-c // receive from c twice.
Run Code Online (Sandbox Code Playgroud)
Golang Spec的Assignement部分允许在以下情况下进行元组赋值:
左边的操作数必须等于右边的表达式数,每个表达式必须是单值的,
nth右边的表达式分配给左边的第n个操作数.