3 回答
TA贡献1862条经验 获得超7个赞
这是一个使用WaitGroup而不是等待固定数量的结果的解决方案。
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
func process(input int, wg *sync.WaitGroup, resultChan chan<- int) {
defer wg.Done()
rand.Seed(time.Now().UnixNano())
n := rand.Intn(5)
time.Sleep(time.Duration(n) * time.Second)
resultChan <- input * 10
}
func main() {
var wg sync.WaitGroup
resultChan := make(chan int)
for i := range []int{1,2,3,4,5} {
wg.Add(1)
go process(i, &wg, resultChan)
}
go func() {
wg.Wait()
close(resultChan)
}()
var result []int
for r := range resultChan {
result = append(result, r)
}
fmt.Println(result)
}
TA贡献1820条经验 获得超9个赞
我更改了您的代码以使用该频道。还有许多其他方法可以使用该频道。
package main
import (
"fmt"
"math/rand"
"time"
)
func process(input int, out chan<- int) {
rand.Seed(time.Now().UnixNano())
n := rand.Intn(5)
time.Sleep(time.Duration(n) * time.Second)
out <- input * 10
}
func main() {
var result []int
resultChan := make(chan int)
items := []int{1, 2, 3, 4, 5}
for _, v := range items {
go process(v, resultChan)
}
for i := 0; i < len(items); i++ {
res, _ := <-resultChan
result = append(result, res)
}
close(resultChan)
fmt.Println(result)
}
更新:(评论的答案)
如果项目数未知,则需要向主发出信号以完成。否则“死锁”,您可以创建一个通道来指示主要功能完成。此外,您可以使用sync.waiteGroup.
对于 Goroutine 中的 panic,你可以使用 defer 和 recover 来处理错误。并且您可以创建一个可以使用的错误通道矿石x/sync/errgroup。
有很多解决方案。这取决于你的问题。所以没有具体的方式来使用 goroutine、channel 和...
TA贡献1845条经验 获得超8个赞
这是一个示例片段,其中我使用通道切片而不是等待组来执行分叉连接:
package main
import (
"fmt"
"os"
)
type cStruct struct {
resultChan chan int
errChan chan error
}
func process(i int) (v int, err error) {
v = i
return
}
func spawn(i int) cStruct {
r := make(chan int)
e := make(chan error)
go func(i int) {
defer close(r)
defer close(e)
v, err := process(i)
if err != nil {
e <- err
return
}
r <- v
return
}(i)
return cStruct{
r,
e,
}
}
func main() {
//have a slice of channelStruct
var cStructs []cStruct
nums := []int{1, 2, 3, 4, 5}
for _, v := range nums {
cStruct := spawn(v)
cStructs = append(cStructs, cStruct)
}
//All the routines have been spawned, now iterate over the slice:
var results []int
for _, c := range cStructs {
rChan, errChan := c.resultChan, c.errChan
select {
case r := <-rChan:
{
results = append(results, r)
}
case err := <-errChan:
{
if err != nil {
os.Exit(1)
return
}
}
}
}
//All the work should be done by now, iterating over the results
for _, result := range results {
fmt.Println("Aggregated result:", result)
}
}
- 3 回答
- 0 关注
- 182 浏览
添加回答
举报
