在for循环中使用并发的goroutines。

huangapple go评论82阅读模式
英文:

Concurrent goroutines inside a for loop

问题

我在for循环中编写了goroutine,希望能够并发地对listofDevices列表中的每个项执行goroutine,但是这段代码只对listofDevices列表中的一个项运行goroutine。

以下是修复这个问题的代码:

for _, ip := range listOfDevices {
    inChan <- types.NewNotification(time.Now(), "/cloudtracer/status", nil,
        &map[key.Key]interface{}{
            key.New(ip): types.Pointer{Pointer: "/cloudtracer/status/" + ip},
        })
    pingOneMachine := probe.NewPing(ip, 2*time.Second, inChan)
    // For now stopping the probe after few minutes. This will change later
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()

    wg.Add(1)
    go func() {
        defer wg.Done()
        pingOneMachine.Run(ctx)
    }()
}
wg.Wait()

希望能帮到你!

英文:

I have written goroutine inside for loop as follow. What I want is to execute the goroutine for each item in the listofDevices list concurrently but this logic is running goroutine for only one item in the listofDevices list.

    for _, ip := range listOfDevices {
            inChan &lt;- types.NewNotification(time.Now(), &quot;/cloudtracer/status&quot;, nil,
                    &amp;map[key.Key]interface{}{
                            key.New(ip): types.Pointer{Pointer: &quot;/cloudtracer/status/&quot; + ip},
                    })
            pingOneMachine := probe.NewPing(ip, 2*time.Second, inChan)
            // For now stopping the probe after few minutes. This will change later
            ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
            defer cancel()

            wg.Add(len(listOfDevices))
            go func() {
                    defer wg.Done()
                    pingOneMachine.Run(ctx)
            }()
    }
    wg.Wait()

Can anyone help me in fixing this out?
thanks in advance.

答案1

得分: 1

尝试使用goroutine闭包:

go func(c context.Context) {
    defer wg.Done()
    pingOneMachine.Run(c)
}(ctx) // 在这里传入词法作用域的变量

也就是说,在for循环中覆盖了ctx变量名,然后在goroutine中使用它(因为变量是词法作用域的),可以参考这个问题的解释:https://stackoverflow.com/questions/25919213/why-does-golang-handle-closures-differently-in-goroutines

基本上,变量是按引用传递的:

这意味着闭包中引用的任何变量都不是副本,而是实际上是一个引用。

英文:

Try using the goroutine closure:

            go func(c context.Context) {
                    defer wg.Done()
                    pingOneMachine.Run(c)
            }(ctx) // pass in the lexically scoped variable here

That is, the ctx variable name is being overridden in the for loop before it is used in the goroutine (as the variables are lexically scoped), see this question for a nice explanation https://stackoverflow.com/questions/25919213/why-does-golang-handle-closures-differently-in-goroutines

Basically variables are passed by reference:

> This means that any variables referenced within the closure from the "outer" scope are not a copy but are in fact a reference.

答案2

得分: 0

以下是要翻译的内容:

for ;;{
    wg.Add(1)
    go func(ip string){
        defer wg.Done()
    }(ip)
}
wg.Wait()

这段代码成功地为所有的IP地址创建了并行的goroutine。

英文:
for ;;{
    wg.Add(1)
    go func(ip string){
        defer wg.Done()
    }(ip)
}
wg.Wait()

It worked in creating parallel goroutines for all the ip addresses.

答案3

得分: -1

按照以下方式进行操作:

for {
    wg.Add(1)
    go func() {
        defer wg.Done()
        // 在这里添加你的代码
    }()
}
wg.Wait()

这段代码使用了一个无限循环来创建并启动 goroutine。每次循环迭代时,都会增加 WaitGroup 的计数器,并在每个 goroutine 完成时减少计数器。最后,通过调用 wg.Wait() 来等待所有 goroutine 完成。你可以在注释的位置添加你自己的代码。

英文:

do it like following

for ;;{
        wg.Add(1)
        go func(){
            defer wg.Done()
        }
    }
    wg.Wait()

huangapple
  • 本文由 发表于 2017年1月3日 17:48:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/41440601.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定