我如何等待对多个其他 Goroutines 的单个 Goroutine 响应?
How can i Await a Single Goroutine Response on Multiple other Goroutines?
大家好,我从 Python3 转到了 Go,所以我正在尝试重写我创建的库以获得更好的性能。
我面临一个问题,因为我是 Golang XD 中的新手,我使用有限的 API 下载数百个 json,我想在以下情况下使用尽可能少的请求我能。
所以在下载那些 jsons 时,一些使用的 URL 是重复的,我得到的第一个想法是在我的下载函数(goroutines)和每个 goroutine 之间传递一个 map[stringLink]*myJsonReceived 在下载之前检查是否 link 已经被另一个 goroutine 处理,所以与其再次请求它并浪费带宽 + API 调用,不如等待其他 goroutine 完成下载并从字典中获取它。
我没有几个选择:
1) goroutine 必须检查 link 是否在地图中,如果是,它每 0.05 秒检查一次字典中的指针是否仍然为零或包含 json。 (可能是最糟糕的方法,但它有效)
2) 将 goroutine 之间传递的映射更改为 (map[stringlink]chan myjson) 这可能是最有效的方式,但我不知道如何将单个消息发送到通道和通过多个等待的 Goroutines 接收它。
3) 我可以通过向结构添加一个计数器来使用选项 (2),每次 goroutine 发现已经请求 url 时,它只需向计数器添加 +1 并等待来自通道的响应,当下载 goroutine 完成时它会发送 X 消息到通道。但是这种方式会让我在地图上添加太多的锁,这是对性能的浪费。
注意:我需要在所有函数执行结束时使用地图将下载的 Json 保存到我的数据库中,以免再次下载它们。
提前感谢大家的帮助。
我想解决你的任务是为此使用 goroutine 池。会有一个生产者在一个通道上发送 URLs,并且工作 goroutines 将在这个通道上范围内接收 URLs 来处理(获取)。一旦 URL 是 "done",同一个 worker goroutine 也可以将其保存到数据库中,或者将结果传递到 "collector" goroutine 的结果通道上,如果是这样的话,它可以按顺序完成保存一个要求。
这种设计结构确保通道上发送的每个 URL 仅由一个工作 goroutine 接收,因此您不需要任何其他同步(在使用共享地图的情况下需要) .有关频道的更多信息,请参阅
Go 支持 goroutines(通道)之间的通信而不是共享变量。引用自 Effective Go: Share by communicating:
Do not communicate by sharing memory; instead, share memory by communicating.
有关如何创建工作器池的示例,请参阅
大家好,我从 Python3 转到了 Go,所以我正在尝试重写我创建的库以获得更好的性能。
我面临一个问题,因为我是 Golang XD 中的新手,我使用有限的 API 下载数百个 json,我想在以下情况下使用尽可能少的请求我能。 所以在下载那些 jsons 时,一些使用的 URL 是重复的,我得到的第一个想法是在我的下载函数(goroutines)和每个 goroutine 之间传递一个 map[stringLink]*myJsonReceived 在下载之前检查是否 link 已经被另一个 goroutine 处理,所以与其再次请求它并浪费带宽 + API 调用,不如等待其他 goroutine 完成下载并从字典中获取它。
我没有几个选择:
1) goroutine 必须检查 link 是否在地图中,如果是,它每 0.05 秒检查一次字典中的指针是否仍然为零或包含 json。 (可能是最糟糕的方法,但它有效)
2) 将 goroutine 之间传递的映射更改为 (map[stringlink]chan myjson) 这可能是最有效的方式,但我不知道如何将单个消息发送到通道和通过多个等待的 Goroutines 接收它。
3) 我可以通过向结构添加一个计数器来使用选项 (2),每次 goroutine 发现已经请求 url 时,它只需向计数器添加 +1 并等待来自通道的响应,当下载 goroutine 完成时它会发送 X 消息到通道。但是这种方式会让我在地图上添加太多的锁,这是对性能的浪费。
注意:我需要在所有函数执行结束时使用地图将下载的 Json 保存到我的数据库中,以免再次下载它们。
提前感谢大家的帮助。
我想解决你的任务是为此使用 goroutine 池。会有一个生产者在一个通道上发送 URLs,并且工作 goroutines 将在这个通道上范围内接收 URLs 来处理(获取)。一旦 URL 是 "done",同一个 worker goroutine 也可以将其保存到数据库中,或者将结果传递到 "collector" goroutine 的结果通道上,如果是这样的话,它可以按顺序完成保存一个要求。
这种设计结构确保通道上发送的每个 URL 仅由一个工作 goroutine 接收,因此您不需要任何其他同步(在使用共享地图的情况下需要) .有关频道的更多信息,请参阅
Go 支持 goroutines(通道)之间的通信而不是共享变量。引用自 Effective Go: Share by communicating:
Do not communicate by sharing memory; instead, share memory by communicating.
有关如何创建工作器池的示例,请参阅