为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
莫回无 2021-06-10 10:13:18
我有并发 goroutines 想要将一个(指向 a 的指针)结构附加到同一个切片。你如何在 Go 中编写它以使其并发安全?这将是我的并发不安全代码,使用等待组:var wg sync.WaitGroupMySlice = 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 通道来保证并发安全。任何人都可以提供一个例子吗?
查看完整描述

3 回答

?
慕妹3242003

TA贡献1824条经验 获得超6个赞

渠道是解决这个问题的最佳方式。这是一个可以在go playground上运行的示例。


package main


import "fmt"

import "sync"

import "runtime"


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()


            // Do stuff.

            runtime.Gosched()


            queue <- T(i)

        }(i)

    }


    // Poll the queue for data and append it to the slice.

    // Since this happens synchronously and in the same

    // goroutine/thread, this can be considered safe.

    go func() {

        defer wg.Done()

        for t := range queue {

            slice = append(slice, t)

        }

    }()


    // Wait for everything to finish.

    wg.Wait()


    fmt.Println(slice)

}

注意:runtime.Gosched()调用存在是因为这些 goroutine 不会让步给调度程序。如果我们没有明确地做一些事情来触发所述调度程序,这将导致死锁。另一种选择可能是执行一些 I/O(例如:打印到标准输出)。但我发现 aruntime.Gosched()的意图更容易和更清晰。


查看完整回答
反对 回复 2021-06-28
  • 3 回答
  • 0 关注
  • 387 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信