英文:
In Go, how do we apply concurrency calls while preserving the order of the list?
问题
给你提供一些背景信息,
变量elementInput
是动态的。我不知道它的确切长度。
它可以是10、5等等。
*Element通道类型是结构体。
我的示例是有效的。但我的问题是这个实现仍然是同步的,因为我正在等待通道返回,以便我可以将其附加到我的结果中。
请问你能帮我如何并发调用GetElements()
函数并保留elementInput
中定义的顺序(基于索引)吗?
elementInput := []string{FB_FRIENDS, BEAUTY_USERS, FITNESS_USERS, COMEDY_USERS}
wg.Add(len(elementInput))
for _, v := range elementInput {
// 创建通道
channel := make(chan *Element)
// 并发调用
go GetElements(ctx, page, channel)
// 保持顺序
var elementRes = <-channel
if len(elementRes.List) > 0 {
el = append(el, elementRes)
}
}
wg.Wait()
英文:
To give you context,
The variable elementInput
is dynamic. I do not know the exact length of it.
It can be 10, 5, or etc.
The *Element channel type is struct
My example is working. But my problem is this implementation is still synchronized, because I am waiting for the channel return so that I can append it to my result
Can you pls help me how to concurrent call GetElements()
function and preserve the order defined in elementInput
(based on index)
elementInput := []string{FB_FRIENDS, BEAUTY_USERS, FITNESS_USERS, COMEDY_USERS}
wg.Add(len(elementInput))
for _, v := range elementInput {
//create channel
channel := make(chan *Element)
//concurrent call
go GetElements(ctx, page, channel)
//Preserve the order
var elementRes = *<-channel
if len(elementRes.List) > 0 {
el = append(el, elementRes)
}
}
wg.Wait()
答案1
得分: 4
你的实现不是并发的。
原因是在每个子程序调用之后,你都在等待结果,这使得它成为串行的。
以下是类似于你的流程的示例实现:
- 调用并发方法,该方法并发调用函数。
- 然后我们循环并收集每个调用的响应。
- 主子程序休眠2秒。
在运行代码的Go Playground中查看示例应用程序-> Sample Application
func main() {
Concurrency()
time.Sleep(2000)
}
func response(greeter string, channel chan *string) {
reply := fmt.Sprintf("hello %s", greeter)
channel <- &reply
}
func Concurrency() {
events := []string{"ALICE", "BOB"}
channels := make([]chan *string, 0)
// 并发启动
for _, event := range events {
channel := make(chan *string)
go response(event, channel)
channels = append(channels, channel)
}
// 收集响应
response := make([]string, len(channels))
for i := 0; i < len(channels); i++ {
response[i] = *<-channels[i]
}
// 打印响应
log.Printf("channel response %v", response)
}
英文:
Your implementation is not concurrent.
> Reason after every subroutine call you are waiting for result, that is making this serial
Below is Sample implementation similar to your flow
- calling Concurreny method which calls function concurrently
- afterwards we loop and collect response from every above call
- main subroutine sleep for 2 seconds
Go PlayGround with running code -> Sample Application
func main() {
Concurrency()
time.Sleep(2000)
}
func response(greeter string, channel chan *string) {
reply := fmt.Sprintf("hello %s", greeter)
channel <- &reply
}
func Concurrency() {
events := []string{"ALICE", "BOB"}
channels := make([]chan *string, 0)
// start concurrently
for _, event := range events {
channel := make(chan *string)
go response(event, channel)
channels = append(channels, channel)
}
// collect response
response := make([]string, len(channels))
for i := 0; i < len(channels); i++ {
response[i] = *<-channels[i]
}
// print response
log.Printf("channel response %v", response)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论