goroutine 接受一个通道接收器并将字符串发送到通道

Lan*_*ara 5 go

我正在尝试创建一个 goroutines 循环,该循环采用接收字符串的通道,并且每次接收到它时都应该将值附加到另一个字符串。只有在所有 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
}
Run Code Online (Sandbox Code Playgroud)

Fli*_*mzy 3

您的代码存在一个问题,即您的 go 例程调用周围的闭包太大。

for _, item := range list {
    go func() {
        doAsyncAndIncrement(item, strReceiver, &currProc)
        str += <-strReceiver 
    }()
}
Run Code Online (Sandbox Code Playgroud)

item作用域为 for 循环,而不是 goroutine 中的匿名函数,因此当您触发 N 个 goroutine 时,您的item变量同时会在 for 循环中更新。为了解决这个问题,请将变量显式传递给你的 goroutine,以避免使用闭包:

for _, item := range list {
    go func(item string) {
        doAsyncAndIncrement(item, strReceiver, &currProc)
        str += <-strReceiver 
    }(item)
}
Run Code Online (Sandbox Code Playgroud)