我如何在多个其他Goroutine上等待一个Goroutine响应?

我如何在多个其他Goroutine上等待一个Goroutine响应?,go,goroutine,Go,Goroutine,嗨,伙计们,我从Python3过来,所以我试图重写我创建的库,以获得更好的性能 我面临一个问题,因为我在Golang XD中使用了noob,我使用有限的API下载了数百个JSON,我希望在可能的情况下使用尽可能少的请求。 因此,在下载这些JSON时,使用的一些URL是重复的,我得到的第一个想法是在下载之前在我的下载函数(goroutines)和每个goroutine之间传递一个map[stringLink]*myJsonReceived,检查链接是否已经被另一个goroutine处理,因此,与其

嗨,伙计们,我从Python3过来,所以我试图重写我创建的库,以获得更好的性能

我面临一个问题,因为我在Golang XD中使用了noob,我使用有限的API下载了数百个JSON,我希望在可能的情况下使用尽可能少的请求。 因此,在下载这些JSON时,使用的一些URL是重复的,我得到的第一个想法是在下载之前在我的下载函数(goroutines)和每个goroutine之间传递一个map[stringLink]*myJsonReceived,检查链接是否已经被另一个goroutine处理,因此,与其再次请求它并浪费带宽+API调用,不如等待另一个goroutine完成下载并从字典中获取它

我几乎没有选择:

1) goroutine必须检查链接是否在映射中,如果是,则每隔0.05秒检查字典中的指针是否仍然为nil或包含json。(可能是最糟糕的方式,但它有效)

2) 将goroutine之间传递的映射更改为(map[stringlink]chan myjson)这可能是最有效的方法,但我不知道如何将单个消息发送到通道,并通过多个等待goroutine接收它

3) 我可以通过向结构添加计数器来使用选项(2),每当goroutine发现url已经被请求时,它只需向计数器添加+1并等待通道的响应,当下载goroutine完成时,它将向通道发送X条消息。但是这种方式会使我在映射中添加太多锁,这是对性能的浪费

注意:我需要在所有函数执行结束时使用映射将下载的JSON保存到我的数据库中,以避免再次下载它们


提前感谢您的帮助。

我想解决您的任务是使用goroutine池来完成此任务。将有一个生产者在一个通道上发送URL,而工作程序goroutines将在该通道上范围以接收要处理(获取)的URL。一旦URL“完成”,同一个工作者goroutine也可以将其保存到数据库中,或者在“收集器”goroutine的结果通道上交付结果,如果需要,该goroutine可以按顺序保存

这种设计构造确保通道上发送的每个URL只由一个worker goroutine接收,因此您不需要任何其他同步(在使用共享映射时需要)。有关频道的详细信息,请参阅

Go支持goroutine(通道)之间的通信,而不是共享变量。引述自:

不要通过共享内存进行交流;相反,通过交流来共享内存


有关如何创建工作池的示例,请参见

hi^^^是的,这是一个好主意,但在将链接放入池中之前,我如何知道链接是否已由制作人处理,而无需使用映射?@sabrobughanmi您将所有URL一次性放入频道。如果您的输入可能多次包含相同的URL,是的,制作者应该构建它们的映射,但是由于制作者应该是单个goroutine,您不需要任何奇特的解决方案或同步。啊,好的,我知道了^ ^ ^所以只有制作人才能开始下载goroutine来解决goroutine同步问题,并且还可以管理映射以在URL重复的情况下返回结果。