猿问

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

大家好,我正在从 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 保存到我的数据库中,以免再次下载它们。

预先感谢大家的帮助。


临摹微笑
浏览 109回答 1
1回答

哈士奇WWW

我想解决你的任务的是我会为此使用一个 goroutine 池。将有一个生产者在通道上发送 URL,而工作 goroutine 将在该通道上范围内接收要处理(获取)的 URL。一旦 URL 被“完成”,同一个 worker goroutine 也可以将其保存到数据库中,或者将结果传递到“collector”goroutine 的结果通道上,如果需要,它可以按顺序完成保存。这种设计结构确保通道上发送的每个 URL 仅由一个工作 goroutine 接收,因此您不需要任何其他同步(在使用共享地图的情况下您需要)。Go 更喜欢 goroutines(通道)之间的通信而不是共享变量。不要通过共享内存进行通信;相反,通过通信共享内存。
随时随地看视频慕课网APP

相关分类

Go
我要回答