alitto / pond

🔘 Minimalistic and High-performance goroutine worker pool written in Go
MIT License
1.5k stars 65 forks source link

Passing variables to function in pool #13

Closed hb0nes closed 3 years ago

hb0nes commented 3 years ago

Hello sir,

This might be a very nooby question, but say I want to do a simple for loop like so:

    pool := pond.New(12, 1000)
    for i := 0; i < 12; i++ {
        pool.Submit(func() {
            log.Println(i)
        })
    }
    pool.StopAndWait()

This will output:

2021/07/09 11:23:26 12
2021/07/09 11:23:26 12
2021/07/09 11:23:26 12
2021/07/09 11:23:26 12
2021/07/09 11:23:26 12
2021/07/09 11:23:26 12
2021/07/09 11:23:26 12
2021/07/09 11:23:26 12
2021/07/09 11:23:26 12
2021/07/09 11:23:26 12
2021/07/09 11:23:26 12
2021/07/09 11:23:26 12

How do I pass variables to functions running in a pool?

p.s.: for comparison, this does seem to work

    for i := 0; i < 12; i++ {
        func() {
            log.Println(i)
        }()
    }
joefrancia commented 3 years ago

You need to copy the loop variable to a local variable like so:

pool := pond.New(12, 1000)
for i := 0; i < 12; i++ {
    j := i
    pool.Submit(func() {
        log.Println(j)
    })
}
pool.StopAndWait()

and you'll get something like

2021/07/09 14:19:37 8
2021/07/09 14:19:37 11
2021/07/09 14:19:37 9
2021/07/09 14:19:37 5
2021/07/09 14:19:37 10
2021/07/09 14:19:37 6
2021/07/09 14:19:37 0
2021/07/09 14:19:37 2
2021/07/09 14:19:37 3
2021/07/09 14:19:37 1
2021/07/09 14:19:37 4
2021/07/09 14:19:37 7
alitto commented 3 years ago

Thanks @scaba! yes, that's the most typical way of doing so. An alternative solution involves creating a self-invoking function as mentioned in https://github.com/alitto/pond/issues/1#issuecomment-618695430 but it's less readable imo.

hb0nes commented 3 years ago

Thanks guys. Much appreciated!