我是Golang的新手,我有一个使用WaitGroup
和Mutex
实现的任务,我想将其转换为使用Channels
。
对该任务的非常简短的描述是:拒绝所需的go例程来处理结果,并在main go例程中等待并收集所有结果。
我使用WaitGroup
和Mutex
的实现如下:
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
func process(input int, wg *sync.WaitGroup, result *[]int, lock *sync.Mutex) *[]int {
defer wg.Done()
defer lock.Unlock()
rand.Seed(time.Now().UnixNano())
n := rand.Intn(5)
time.Sleep(time.Duration(n) * time.Second)
lock.Lock()
*result = append(*result, input * 10)
return result
}
func main() {
var wg sync.WaitGroup
var result []int
var lock sync.Mutex
for i := range []int{1,2,3,4,5} {
wg.Add(1)
go process(i, &wg, &result, &lock)
}
}
如何使用
Mutex
代替使用Channels
的内存同步?我的主要问题是我不确定如何确定正在处理最终任务的最终执行例程,因此是否有一个要关闭
channel
的例程。这个想法是,通过关闭channel
,主要的go例程可以遍历channel
,检索结果,并且当发现channel
已关闭时,它将继续运行。在这种情况下,关闭 channel 的方法也可能是错误的方法,因此,我在这里问为什么。
经验丰富的Go程序员将如何使用
channels
解决此问题?
最佳答案
这是使用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)
}
关于go - 如何使用 channel 收集各种goroutine的响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61821424/