为什么这段代码没有打印出20个问候语?

huangapple go评论70阅读模式
英文:

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 (
	&quot;log&quot;
	&quot;math/rand&quot;
	&quot;time&quot;
)

func SayGreetings(greeting string, times int) {
	for i := 0; i &lt; 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(&quot;hi!&quot;, 10)
	go SayGreetings(&quot;hello!&quot;, 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!
英文:
  1. Increase the sleep time to time.Sleep(20 *time.Second) in main
package main

import (
	&quot;log&quot;
	&quot;math/rand&quot;
	&quot;time&quot;
)

func SayGreetings(greeting string, times int) {
	for i := 0; i &lt; 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(&quot;hi!&quot;, 10)
	go SayGreetings(&quot;hello!&quot;, 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!

huangapple
  • 本文由 发表于 2022年10月5日 18:18:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/73958971.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定