为了账号安全,请及时绑定邮箱和手机立即绑定

我如何等待对多个其他 Goroutines 的单个 Goroutine 响应?

我如何等待对多个其他 Goroutines 的单个 Goroutine 响应?

Go
临摹微笑 2023-06-12 12:50:59
大家好,我正在从 Python3 转到 Go,所以我正在尝试重写我创建的库以获得更好的性能。我面临一个问题,因为我是 Golang XD 中的新手,我使用有限的 API 下载数百个 json,我想尽可能少地使用请求。所以在下载那些 jsons 时,一些使用的 URL 是重复的,我得到的第一个想法是在我的下载函数(goroutines)和每个 goroutine 之间传递一个 map[stringLink]*myJsonReceived 在下载之前检查链接是否已经被另一个 goroutine 处理,因此与其再次请求它并浪费带宽 + API 调用,不如等待其他 goroutine 完成下载并从字典中获取它。我有几个选择:1) goroutine 必须检查链接是否在地图中,如果是的话,它每 0.05 秒检查一次字典中的指针是否仍然为零或包含 json。(可能是最糟糕的方法,但它有效)2) 将 goroutine 之间传递的映射更改为 (map[stringlink]chan myjson) 这可能是最有效的方式,但我不知道如何将单个消息发送到通道并由多个等待的 Goroutine 接收它。3)我可以通过向结构添加一个计数器来使用选项(2),并且每次 goroutine 发现已经请求了 url 时,它只是将 +1 添加到计数器并等待来自通道的响应,当下载 goroutine完成后,它将向通道发送 X 条消息。但是这种方式会让我在地图上添加太多的锁,这是一种性能浪费。注意:我需要在所有函数执行结束时使用地图将下载的 Json 保存到我的数据库中,以免再次下载它们。预先感谢大家的帮助。
查看完整描述

1 回答

?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

我想解决你的任务的是我会为此使用一个 goroutine 池。将有一个生产者在通道上发送 URL,而工作 goroutine 将在该通道上范围内接收要处理(获取)的 URL。一旦 URL 被“完成”,同一个 worker goroutine 也可以将其保存到数据库中,或者将结果传递到“collector”goroutine 的结果通道上,如果需要,它可以按顺序完成保存。

这种设计结构确保通道上发送的每个 URL 仅由一个工作 goroutine 接收,因此您不需要任何其他同步(在使用共享地图的情况下您需要)。

Go 更喜欢 goroutines(通道)之间的通信而不是共享变量。

不要通过共享内存进行通信;相反,通过通信共享内存。

查看完整回答
反对 回复 2023-06-12
  • 1 回答
  • 0 关注
  • 108 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信