我正在尝试创建一个循环的goroutine,它接受一个接收字符串的通道,每次收到它时,它都应该将值附加到另一个字符串。只有在所有goroutine的末尾(goroutine计数应该是传入的list
的长度),代码应该继续。
下面的示例似乎没有将strReceiver
频道中的值附加到str
,因为str永远不会被修改。
任何人都知道什么是错的?
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
}
答案 0 :(得分:1)
你的代码的一个问题是你的go例程调用的闭包太大了。
for _, item := range list {
go func() {
doAsyncAndIncrement(item, strReceiver, &currProc)
str += <-strReceiver
}()
}
item
的范围是for循环,而不是你的goroutine中的匿名函数,所以当你启动N goroutines时,你的item
变量同时在for循环中更新。要解决此问题,请将变量显式传递给goroutine,以避免使用闭包:
for _, item := range list {
go func(item string) {
doAsyncAndIncrement(item, strReceiver, &currProc)
str += <-strReceiver
}(item)
}