英文:
Why does this not print out 20 greetings?
问题
我正在学习Golang,并且在努力理解为什么这段代码没有打印出20个问候语,尽管我调用了两次函数,每次都调用了10次。
package main
import (
"log"
"math/rand"
"time"
)
func SayGreetings(greeting string, times int) {
for i := 0; i < times; i++ {
log.Println(greeting)
d := time.Second * time.Duration(rand.Intn(5)) / 2
time.Sleep(d) // 睡眠0到2.5秒
}
}
func main() {
rand.Seed(time.Now().UnixNano())
log.SetFlags(0)
go SayGreetings("hi!", 10)
go SayGreetings("hello!", 10)
time.Sleep(2 * time.Second)
}
这段代码使用了goroutine来并发地调用SayGreetings
函数。由于goroutine是并发执行的,所以在主函数中的time.Sleep(2 * time.Second)
语句只会等待2秒钟,而不会等待goroutine执行完毕。因此,可能会出现打印不完整的情况。
如果你想要确保所有的问候语都被打印出来,可以使用sync.WaitGroup
来等待goroutine执行完毕。具体的做法是在main
函数中创建一个sync.WaitGroup
对象,并在每个goroutine开始时调用Add
方法,在goroutine结束时调用Done
方法。最后,调用Wait
方法来等待所有的goroutine执行完毕。以下是修改后的代码:
package main
import (
"log"
"math/rand"
"sync"
"time"
)
func SayGreetings(greeting string, times int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < times; i++ {
log.Println(greeting)
d := time.Second * time.Duration(rand.Intn(5)) / 2
time.Sleep(d) // 睡眠0到2.5秒
}
}
func main() {
rand.Seed(time.Now().UnixNano())
log.SetFlags(0)
var wg sync.WaitGroup
wg.Add(2)
go SayGreetings("hi!", 10, &wg)
go SayGreetings("hello!", 10, &wg)
wg.Wait()
}
这样修改后,main
函数会等待所有的goroutine执行完毕后再退出,确保所有的问候语都被打印出来。
英文:
I'm learning Golang and am struggling to understand why this isn't printing out 20 greetings even though I'm calling the function twice with 10 times each.
package main
import (
"log"
"math/rand"
"time"
)
func SayGreetings(greeting string, times int) {
for i := 0; i < times; i++ {
log.Println(greeting)
d := time.Second * time.Duration(rand.Intn(5)) / 2
time.Sleep(d) // sleep for 0 to 2.5 seconds
}
}
func main() {
rand.Seed(time.Now().UnixNano())
log.SetFlags(0)
go SayGreetings("hi!", 10)
go SayGreetings("hello!", 10)
time.Sleep(2 * time.Second)
}
答案1
得分: 1
非常简单解释。你使用go关键字两次调用了SayGreetings
函数,这导致了两个并发执行的SayGreetings函数。最后你没有等待两个函数都执行完毕!你的代码只在调用两个函数后等待了2秒,而每个函数都等待了超过两秒。
所以你要么增加主函数中的等待时间,要么等待两个函数都执行完毕。
你的问题类似于https://stackoverflow.com/questions/64674051/wait-for-concurrent-workers-to-finish-before-exiting
英文:
Very simple to explain. You call SayGreetings
twice with the go keyword, which causes two concurrent executions of the SayGreetings function. At the end you don't wait until both functions finish! Your code only waits for 2 seconds after calling both functions, each function waits for more than two seconds.
So you either increase the wait time in main, or wait until both functions finish
Your issue is similar to https://stackoverflow.com/questions/64674051/wait-for-concurrent-workers-to-finish-before-exiting
答案2
得分: 0
将主函数中的睡眠时间增加到time.Sleep(20 * time.Second)
。
package main
import (
"log"
"math/rand"
"time"
)
func SayGreetings(greeting string, times int) {
for i := 0; i < times; i++ {
log.Println(greeting)
d := time.Second * time.Duration(rand.Intn(5)) / 2
time.Sleep(d) // 睡眠0到2.5秒
}
}
func main() {
rand.Seed(time.Now().UnixNano())
log.SetFlags(0)
go SayGreetings("hi!", 10)
go SayGreetings("hello!", 10)
time.Sleep(20 * time.Second)
}
输出:
======
hi!
hi!
hello!
hello!
hi!
hello!
hi!
hello!
hello!
hi!
hello!
hi!
hi!
hello!
hello!
hello!
hi!
hello!
hi!
hi!
英文:
- Increase the sleep time to
time.Sleep(20 *time.Second)
in main
package main
import (
"log"
"math/rand"
"time"
)
func SayGreetings(greeting string, times int) {
for i := 0; i < times; i++ {
log.Println(greeting)
d := time.Second * time.Duration(rand.Intn(5)) / 2
time.Sleep(d) // sleep for 0 to 2.5 seconds
}
}
func main() {
rand.Seed(time.Now().UnixNano())
log.SetFlags(0)
go SayGreetings("hi!", 10)
go SayGreetings("hello!", 10)
time.Sleep(20 * time.Second)
}
Output:
======
hi!
hi!
hello!
hello!
hi!
hello!
hi!
hello!
hello!
hi!
hello!
hi!
hi!
hello!
hello!
hello!
hi!
hello!
hi!
hi!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论