Dan*_*e B 24 concurrency append go goroutine
我有并发的goroutine想要将(指向a)指针结构附加到同一个切片.你如何在Go中编写它以使其兼容并发?
这将是我使用等待组的并发不安全代码:
var wg sync.WaitGroup
MySlice = make([]*MyStruct)
for _, param := range params {
    wg.Add(1)
    go func(param string) {
        defer wg.Done()
        OneOfMyStructs := getMyStruct(param)
        MySlice = append(MySlice, &OneOfMyStructs)
    }(param)
}
wg.Wait()
Run Code Online (Sandbox Code Playgroud)
我想你需要使用go渠道来实现并发安全.任何人都可以贡献一个例子吗?
Vol*_*ker 25
MySlice = append(MySlice, &OneOfMyStructs)使用sync.Mutex 保护没有任何问题.但是当然你可以有一个缓冲区大小的结果通道len(params)所有goroutines发送他们的答案,一旦你的工作完成,你从这个结果通道收集.
如果您params的尺寸固定:
MySlice = make([]*MyStruct, len(params))
for i, param := range params {
    wg.Add(1)
    go func(i int, param string) {
         defer wg.Done()
         OneOfMyStructs := getMyStruct(param)
         MySlice[i] = &OneOfMyStructs
     }(i, param)
}
Run Code Online (Sandbox Code Playgroud)
由于所有goroutines写入不同的记忆,这不是很有趣.
chr*_*ris 14
@jimt发布的答案不太正确,因为它错过了在频道中发送的最后一个值,而且defer wg.Done()从未调用过最后一个值.下面的代码段有更正.
https://play.golang.org/p/7N4sxD-Bai
package main
import "fmt"
import "sync"
type T int
func main() {
    var slice []T
    var wg sync.WaitGroup
    queue := make(chan T, 1)
    // Create our data and send it into the queue.
    wg.Add(100)
    for i := 0; i < 100; i++ {
        go func(i int) {
            // defer wg.Done()  <- will result in the last int to be missed in the receiving channel
            queue <- T(i)
        }(i)
    }
    go func() {
        // defer wg.Done() <- Never gets called since the 100 `Done()` calls are made above, resulting in the `Wait()` to continue on before this is executed
        for t := range queue {
            slice = append(slice, t)
            wg.Done()   // ** move the `Done()` call here
        }
    }()
    wg.Wait()
    // now prints off all 100 int values
    fmt.Println(slice)
}
Run Code Online (Sandbox Code Playgroud)