go - 处理具有一个“返回”值的 goroutine 的惯用方式?
问题描述
想象一下,我想编写一个返回随机数除以 2 的函数:
func randomIntInHalf() int {
return rand.Int() / 2
}
但后来我决定要为并发构建这个函数,所以我最终得到:
func randomIntInHalf(c chan<- int) {
c <- rand.Int() / 2
}
func main() {
// Generate 10 random ints in parallel
amount := 10
c := make(chan int, amount)
for i := 0; i < amount; i++ {
go randomIntInHalf(c)
}
for i := 0; i < amount; i++ {
fmt.Println(<-c)
}
close(c)
}
我看到这种方法存在一些问题。例如,我要求调用者在通道完成生成后关闭通道,从而可能有人调用该函数并无限期地保持通道打开。我的理解是,您总是希望发件人关闭频道。A)这是真的吗,b)在这种情况下甚至可能吗?有没有更好的方法来编写此代码或解决此问题?
而且,一般来说,是否有更好的惯用方法来并行运行只向通道写入 1(或已知 N)值的函数?
谢谢。
解决方案
您不需要关闭频道。一旦超出范围,它将被垃圾收集。关闭通道通常用于向done
侦听器发送通知。所以在你的情况下甚至不可能。
您的方法是您要实现的目标的惯用方法,但不是唯一的方法。我能想到的其他一些(不一定是惯用的)是:
- 您可以使用共享数据结构并通过显式同步从多个 goroutine 填充该结构,
- 您可以为每个 goroutine 保留一个单独的结果,并传入一个指向它的指针。每个 goroutine 设置它的结果而不需要同步,当一切都完成后,调用者处理结果。
推荐阅读
- android - Cordova 找不到 Theme.AppCompat.Light
- reactjs - 在屏幕 React-Native 之间导航
- cmd - 如何将特定扩展名的文件从当前文件夹添加到 Windows 10 上的路径
- swift - 从核心数据数组中删除重复元素
- c++ - 抑制单行的弃用警告
- python - 如果对象在pickle文件中不存在,则创建新对象,如果存在则加载它(使用多个对象的最佳方法?)
- keras - 在 ResNet 网络顶部添加层时图形断开连接
- angular - 当 Angular 7 的 Microsoft Edge 中的值更改时,绑定无法立即工作
- javascript - 在 Vue 方法上使用 promise 和 await 时出现问题
- laravel-5 - Laravel 5.7 在同一页面上使用登录和注册表单时如何区分错误消息?