英文:
Why can't this program print anything using goroutine?
问题
我最近在研究谷歌的Golang,并遇到了以下问题。然后程序没有打印任何内容。但是如果我删除"go"标记,它将打印出"goroutine"和"going"两个词。
package main
import "fmt"
func f(msg string) {
fmt.Println(msg)
return
}
func main() {
go f("goroutine")
go func(msg string) {
fmt.Println(msg)
return
}("going")
return
}
英文:
I'm recently looking into Golang by google and I met with the following problem. Then program doesn't print anything. But if I remove the "go" notations, it will print both "goroutine" and "going".
package main
import "fmt"
func f(msg string) {
fmt.Println(msg)
return
}
func main() {
go f("goroutine")
go func(msg string) {
fmt.Println(msg)
return
}("going")
return
}
答案1
得分: 8
你的程序在goroutine执行之前就退出了。你可以稍微等待一下,例如通过调用time.Sleep(2 * time.Second)
,但这种行为被认为是不好的实践,因为你的程序可能运行时间超过2秒,然后仍然终止。
更好的方法是使用sync.WaitGroup
:
package main
import (
"fmt"
"sync"
)
func f(msg string, wg *sync.WaitGroup) {
fmt.Println(msg)
wg.Done()
}
func main() {
var wg sync.WaitGroup
wg.Add(1)
go f("goroutine", &wg)
wg.Add(1)
go func(msg string) {
fmt.Println(msg)
wg.Done()
}("going")
wg.Wait()
}
英文:
You program exits before the goroutines is executed. You could wait a little bit, for example by calling time.Sleep(2 * time.Second)
, but such behaviour is considered bad practice, since your program could run longer than 2 seconds and would then terminate nonetheless.
A better approach is to use sync.WaitGroup
:
package main
import (
"fmt"
"sync"
)
func f(msg string, wg *sync.WaitGroup) {
fmt.Println(msg)
wg.Done()
}
func main() {
var wg sync.WaitGroup
wg.Add(1)
go f("goroutine", &wg)
wg.Add(1)
go func(msg string) {
fmt.Println(msg)
wg.Done()
}("going")
wg.Wait()
}
答案2
得分: 5
你的代码需要在退出之前等待例程完成。一种好的方法是传入一个通道,例程使用该通道来发出完成信号,然后在主代码中等待。请参考下面的代码。
这种方法的另一个优点是它允许/鼓励你根据返回值进行适当的错误处理。
package main
import (
"fmt"
)
func f(msg string, quit chan int) {
fmt.Println(msg)
quit <- 0
return
}
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
go f("goroutine", ch1)
go func(msg string, quit chan int) {
fmt.Println(msg)
quit <- 0
return
}("going", ch2)
<-ch1
<-ch2
return
}
英文:
Your code needs to wait for the routines to finish before exiting. A good way to do this is to pass in a channel which is used by the routine to signal when it's done and then wait in the main code. See below.
Another advantage of this approach is that it allows/encourages you to perform proper error handling based on the return value.
package main
import (
"fmt"
)
func f(msg string, quit chan int) {
fmt.Println(msg)
quit <- 0
return
}
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
go f("goroutine", ch1)
go func(msg string, quit chan int) {
fmt.Println(msg)
quit <- 0
return
}("going", ch2)
<-ch1
<-ch2
return
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论