我想通过启动几个工人goroutines来加速Go的某项任务。
在下面的example中,我正在寻找一个"宝贝"。启动的工人goroutines将永远挖掘物品,直到他们被告知停止。如果该物品是通缉宝,则将其放置在共享缓冲通道上,其容量等于工人数量。
该计划只对获得一个宝藏感兴趣。它还必须确保所有工人goroutine将返回而不是永远被阻止。
该示例有效,但有没有更清洁或更惯用的方法来确保上述内容?
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
var wg sync.WaitGroup
func digTreasure() int {
time.Sleep(5 * time.Millisecond)
return rand.Intn(1000)
}
func worker(i int, ch chan int, quit chan struct{}) {
defer func() {
fmt.Println("worker", i, "left")
wg.Done()
}()
for {
treasure := digTreasure()
if treasure%100 == 0 {
fmt.Println("worker", i, "found treasure", treasure)
ch <- treasure
return
}
select {
case <-quit:
fmt.Println("worker", i, "quitting")
return
default:
}
}
}
func main() {
rand.Seed(time.Now().UnixNano())
n := 10
ch, quit := make(chan int, n), make(chan struct{})
fmt.Println("Searching...")
wg.Add(n)
for i := 0; i < n; i++ {
go worker(i, ch, quit)
}
fmt.Println("I found treasure:", <-ch)
close(quit)
wg.Wait()
fmt.Println("All workers left")
}