I am trying to make a loop of goroutines that take a channel that receives strings, and every time it is received it should append the value to another string. Only at the end of all goroutines (the goroutine count should be the length of the list
passed in), should the code continue on.
My example below doesn't seem to append the values from the strReceiver
channel onto str
, because str is never modified.
Anyone know what's wrong?
func appendToStr(str string, list []string, origin *url.URL) {
var currProc int32 = 0;
var maxProc int32 = int32(len(list))
var strReceiver := make(chan string, len(list))
for _, item := range list {
go func() {
doAsyncAndIncrement(item, strReceiver, &currProc)
str += <-strReceiver
}()
}
for {
if atomic.LoadInt32(&currProc) <= maxProc {
break;
}
}
// continue on using 'str' which now contains the append values from the 'strReceiver' channel
}
func doAsyncAndIncrement(item string, receiver chan<- string, count *int32) {
defer atomic.AddInt32(count, 1)
var val string
// do something with 'item' and set 'val'...
receiver <- val
}
One problem with your code is that the closure around your go routine invocation is too big.
for _, item := range list {
go func() {
doAsyncAndIncrement(item, strReceiver, &currProc)
str += <-strReceiver
}()
}
item
is scoped to the for loop, not the anonymous function in your goroutine, so while you firing off N goroutines, your item
variable meanwhile is being updated in a for loop. To remedy this, pass the variable to your goroutine explicitly, to avoid using a closure:
for _, item := range list {
go func(item string) {
doAsyncAndIncrement(item, strReceiver, &currProc)
str += <-strReceiver
}(item)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With