英文:
First goroutine example, weird results
问题
这个例子来自tour.golang.org/#63
<!-- 注释因为编辑必须超过6个字符 -->
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
输出结果
hello
world
hello
world
hello
world
hello
world
hello
为什么world
只打印了4
次而不是5
次?
编辑: 答案可以从golang规范中引用:
> 程序的执行从初始化主包开始,然后调用main函数。当main函数返回时,程序退出。它不会等待其他(非主)goroutine完成。
英文:
This example taken from tour.golang.org/#63
<!-- comment because edit must be more than 6 chars -->
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
The output
hello
world
hello
world
hello
world
hello
world
hello
Why world
is printed only 4
times instead of 5
?
Edit: The answer can be quoted from golang specification:
> Program execution begins by initializing the main package and then
> invoking the function main. When the function main returns, the
> program exits. It does not wait for other (non-main) goroutines to
> complete.
答案1
得分: 5
当你的主函数结束时,程序也会结束,也就是说所有的goroutine都会被终止。
在go say("world")
完成之前,你的主函数就已经终止了。如果你在主函数的末尾加上一些睡眠时间,你应该能看到最后的"world"。
英文:
When your main function ends your program ends, i.e. all goroutines are terminated.
Your main terminates before go say("world")
is done. If you sleep some time at the end of main you should see the last world.
答案2
得分: 4
这是如何正确解决同步问题的方法 - 使用sync.WaitGroup。
package main
import (
"fmt"
"sync"
"time"
)
func say(s string, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
wg := new(sync.WaitGroup)
wg.Add(2)
go say("world", wg)
go say("hello", wg)
wg.Wait()
fmt.Println("All done")
}
英文:
Here is how you solve that synchronization problem properly - with sync.WaitGroup
package main
import (
"fmt"
"sync"
"time"
)
func say(s string, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
wg := new(sync.WaitGroup)
wg.Add(2)
go say("world", wg)
go say("hello", wg)
wg.Wait()
fmt.Println("All done")
}
答案3
得分: 2
因为调用的goroutine在你创建的第二个goroutine之前终止,这导致第二个goroutine关闭。为了说明这一点,稍微修改一下你的代码:
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Print(i)
fmt.Println(":" + s)
}
}
func main() {
go say("world")
say("hello")
time.Sleep(1 * time.Second) // 在main函数的末尾加上一个等待或者睡眠
}
在main函数的末尾加上一个等待或者睡眠的操作。
英文:
Because the calling gorouting terminates before the second one you spawned does. This causes the second to shut down. To illustrate, modify your code slightly:
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Print(i)
fmt.Println(":"+s)
}
}
func main() {
go say("world")
say("hello")
}
Try putting in a "wait" or a sleep to the end of the main function.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论