如何修改这段Go代码使其在3秒内执行完成?
嘿,我来帮你搞定这个Go代码的耗时问题!
为什么原代码会跑6秒?
你原来的代码里,_, _ = <-worker(), <-worker()这行是顺序执行的:程序会先等着第一个worker()返回的channel出结果(这要等3秒),等拿到第一个结果后,才会去调用第二个worker()并等待它的结果。相当于两个3秒的任务是串行跑的,加起来就6秒啦。
怎么改成3秒跑完?
核心就是让两个worker的goroutine并行执行,也就是让它们同时开始睡3秒,而不是等第一个睡完再睡第二个。这里给你两种简单的修改方式:
方式一:先存好两个channel,再同时等结果
这种方式最贴合你原来的代码结构,改动最小:
package main import ( "time" ) func worker() chan int { ch := make(chan int) go func() { time.Sleep(3 * time.Second) ch <- 42 }() return ch } func main() { timeStart := time.Now() // 先把两个worker的channel都拿到,这时候两个goroutine已经同时启动开始睡觉了 ch1 := worker() ch2 := worker() // 再同时等两个channel的结果 _, _ = <-ch1, <-ch2 println(int(time.Since(timeStart).Seconds())) // 现在就会输出3啦 }
方式二:用sync.WaitGroup(适合后续扩展更多worker的场景)
如果以后你要启动更多的worker,用WaitGroup来管理会更清晰:
package main import ( "sync" "time" ) func worker(wg *sync.WaitGroup) { defer wg.Done() // 任务完成时告诉WaitGroup我搞定了 time.Sleep(3 * time.Second) // 这里可以加你需要的业务逻辑,比如处理数据啥的 } func main() { timeStart := time.Now() var wg sync.WaitGroup // 告诉WaitGroup我们要启动2个worker wg.Add(2) // 同时启动两个goroutine go worker(&wg) go worker(&wg) // 等着所有worker都完成 wg.Wait() println(int(time.Since(timeStart).Seconds())) // 同样输出3 }
原理简单说下
第一种方式里,先调用两次worker()会立刻启动两个独立的goroutine,它们会同时开始3秒的睡眠。等你再去接收两个channel的结果时,两个goroutine已经在并行跑了,所以总耗时就是3秒(两个任务同时完成)。
第二种方式用WaitGroup来跟踪每个goroutine的状态,同样是让两个任务并行执行,等所有任务都结束后再继续往下走,自然总耗时就是3秒啦。
内容的提问来源于stack exchange,提问作者NehaJ
相关产品推荐
相关产品推荐

