英文:
Order of execution inside go routines
问题
我最近开始学习Go语言,对于这个程序的执行顺序感到非常困惑。希望我在这里没有问一些非常琐碎的问题。
这基本上是Go语言之旅中的第69个例子,我插入了一些Println语句;Playground链接:http://play.golang.org/p/PXDlD3EA2f
func fibonacci(c, quit chan int) {
x, y := 0, 1
fmt.Println("Inside the fibonacci")
for {
select {
case c <- x:
fmt.Println("Inside the for, first case, before reassigning ", x, y)
x, y = y, x+y
fmt.Println("Inside the for, first case, after reassigning ", x, y)
case <-quit:
fmt.Println("quit")
return
}
}
}
func main() {
fmt.Println("Begin of Main")
c := make(chan int)
quit := make(chan int)
fmt.Println("Before going to the func")
go func() {
fmt.Println("Inside go routine")
fmt.Println("Inside go routine... again")
for i := 0; i < 10; i++ {
fmt.Println("Inside go routine and the for, before printing the channel")
fmt.Println(<-c)
}
quit <- 0
}()
fmt.Println("Before calling to fibonacci")
fibonacci(c, quit)
fmt.Println("Closing")
}
在我得到的非常冗长的输出中(见下面附图),有几件事我不明白:
-
为什么"Inside the fibonacci"这一行在go例程中的行之前?这是因为在go命令之后,编译器同时在func和fibonacci中读取吗?
-
fibonacci和func是如何交互的?func没有改变通道c,那为什么fibonacci会有反应?是谁改变了c?
-
为什么在fibonacci中每次都有5个打印输出?老实说,我只期望有2个。
函数的输出结果:
英文:
I recently started with go and I am really confused about the order of execution of this program. I hope I am not asking really trivial questions here.
This is basically #69 in the golang tour, with some Println I have inserted; Link to playground: http://play.golang.org/p/PXDlD3EA2f
func fibonacci(c, quit chan int) {
x, y := 0, 1
fmt.Println("Inside the fibonacci")
for {
select {
case c <- x:
fmt.Println("Inside the for, first case, before reassigning ", x, y)
x, y = y, x+y
fmt.Println("Inside the for, first case, after reassigning ", x, y)
case <-quit:
fmt.Println("quit")
return
}
}
}
func main() {
fmt.Println("Begin of Main")
c := make(chan int)
quit := make(chan int)
fmt.Println("Before gonig to the func")
go func() {
fmt.Println("Inside go routine")
fmt.Println("Inside go routine... again")
for i := 0; i < 10; i++ {
fmt.Println("Inside go routine and the for, before printing the channel")
fmt.Println(<-c)
}
quit <- 0
}()
fmt.Println("Before calling to fibonacci")
fibonacci(c, quit)
fmt.Println("Closing")
}
In the very verbose output I obtain (see attached image below), there are a couple of things I do not understand:
-
why is the "Inside the fibonacci" line before the ones in the go routine? Is this because after the go command, the compiler is just reading at the same time inside func and fibonacci?
-
how do fibonacci and func interact? func is not changing the channel c, so why is fibonacci reacting? Who's changing c?
-
why inside fibonacci there are 5 prints together every time? Honesty I was expecting only 2.
Output of the function:
答案1
得分: 6
让我们一步一步来解释:
* 为什么"go routine"中的"Inside the fibonacci"行在函数中的行之前?这是因为在使用"go"命令之后,编译器同时在函数和fibonacci中读取吗?
因为你的"go routine"实际上是在调用fibonacci
之后开始的,调度器需要一点时间来启动。例如,如果你启动一个调用fmt.Println
的"go routine",并且在"main"中没有等待的操作,程序将在执行之前退出。
* fibonacci和func是如何交互的?func没有改变通道c,为什么fibonacci会有反应?谁改变了c?
fibonacci
将数字推送到通道中,注意这部分代码:
select {
case c <- x: //这是将x发送到通道中
* 为什么每次在fibonacci中有5个打印输出?我本来期望只有2个。
这再次取决于调度器以及fmt.Print*
不会锁定stdout,输出的顺序可以是任意的,因为它是两个不同的线程打印的内容。
英文:
Let's take it step by step:
* why is the "Inside the fibonacci" line before the ones in the go routine? Is this because after the go command, the compiler is just reading at the same time inside func and fibonacci?
Because your go routine actually starts after you call fibonacci
, the scheduler takes a little bit of time to start, for example if you start a goroutine that calls fmt.Println
and do nothing to wait in main
, the program will exit before it gets executed.
* how do fibonacci and func interact? func is not changing the channel c, so why is fibonacci reacting? Who's changing c?
fibonacci
is pushing numbers into the channel, notice this part:
select {
case c <- x: //this is sending x to the channel
* why inside fibonacci there are 5 prints together every time? Honesty I was expecting only 2.
That again depends on the scheduler and the fact that fmt.Print*
doesn't lock stdout, the output can happen in any order since it's 2 different threads printing stuff.
答案2
得分: 1
这个演示非常有用,可以帮助你理解通道的工作原理:Google I/O 2012 - Go Concurrency Patterns。在这个视频中,你可以找到你问题的答案。
英文:
Not really an answer, but i found this presentation very handy to understand how channels work: Google I/O 2012 - Go Concurrency Patterns
In here you find answers for your questions.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论