Golang 并发:如何从不同的 goroutine 附加到同一个切片

我有并发 goroutines 想要将一个(指向 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()

我想你需要使用 go 通道来保证并发安全。任何人都可以提供一个例子吗?


莫回无
浏览 394回答 3
3回答

慕妹3242003

渠道是解决这个问题的最佳方式。这是一个可以在go playground上运行的示例。package mainimport "fmt"import "sync"import "runtime"type T intfunc main() {&nbsp; &nbsp; var slice []T&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; queue := make(chan T, 1)&nbsp; &nbsp; // Create our data and send it into the queue.&nbsp; &nbsp; wg.Add(100)&nbsp; &nbsp; for i := 0; i < 100; i++ {&nbsp; &nbsp; &nbsp; &nbsp; go func(i int) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Do stuff.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; runtime.Gosched()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; queue <- T(i)&nbsp; &nbsp; &nbsp; &nbsp; }(i)&nbsp; &nbsp; }&nbsp; &nbsp; // Poll the queue for data and append it to the slice.&nbsp; &nbsp; // Since this happens synchronously and in the same&nbsp; &nbsp; // goroutine/thread, this can be considered safe.&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; for t := range queue {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; slice = append(slice, t)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }()&nbsp; &nbsp; // Wait for everything to finish.&nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; fmt.Println(slice)}注意:runtime.Gosched()调用存在是因为这些 goroutine 不会让步给调度程序。如果我们没有明确地做一些事情来触发所述调度程序,这将导致死锁。另一种选择可能是执行一些 I/O(例如:打印到标准输出)。但我发现 aruntime.Gosched()的意图更容易和更清晰。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go