go - 如何在运行例程时将值分配给结构?

标签 go concurrency goroutine

我在我的项目中使用 goroutines,我想将值分配给结构字段,但我不知道我将如何分配通过使用 mongodb 查询获得的值到我正在展示的结构字段结构和查询也是如此。

type AppLoadNew struct{
    StripeTestKey      string                   `json:"stripe_test_key" bson:"stripe_test_key,omitempty"`
    Locations          []Locations              `json:"location" bson:"location,omitempty"`
}

type Locations struct{
   Id int `json:"_id" bson:"_id"`
   Location  string `json:"location" bson:"location"`
}

func GoRoutine(){
   values := AppLoadNew{}
   go func() {
      data, err := GetStripeTestKey(bson.M{"is_default": true})
      if err == nil {
        values.StripeTestKey := data.TestStripePublishKey
      }
  }()
  go func() {
      location, err := GetFormLocation(bson.M{"is_default": true})
      if err == nil {
        values.Locations := location
      }
  }()
  fmt.Println(values) // Here it will nothing
  // empty
}

你能帮我把所有的值赋给 AppLoadNew 结构吗。

最佳答案

在 Go 中,没有值对于并发读写(来自多个 goroutines)是安全的。您必须同步访问。

可以使用 sync.Mutex 保护从多个 goroutine 读取和写入变量或 sync.RWMutex ,但在您的情况下还涉及其他内容:您应该等待 2 个启动的 goroutines 完成。为此,首选解决方案是 sync.WaitGroup .

并且由于 2 个 goroutines 写入一个结构的 2 个不同字段(充当 2 个不同的变量),因此它们不必相互同步(请在此处查看更多信息:Can I concurrently write different slice elements)。这意味着使用 sync.WaitGroup 就足够了。

这是使它安全和正确的方法:

func GoRoutine() {
    values := AppLoadNew{}

    wg := &sync.WaitGroup{}

    wg.Add(1)
    go func() {
        defer wg.Done()
        data, err := GetStripeTestKey(bson.M{"is_default": true})
        if err == nil {
            values.StripeTestKey = data.StripeTestKey
        }
    }()

    wg.Add(1)
    go func() {
        defer wg.Done()
        location, err := GetFormLocation(bson.M{"is_default": true})
        if err == nil {
            values.Locations = location
        }
    }()

    wg.Wait()
    fmt.Println(values)
}

请参阅 Go Playground 上的(稍作修改的)工作示例.

查看相关/类似问题:

Reading values from a different thread

golang struct concurrent read and write without Lock is also running ok?

How to make a variable thread-safe

关于go - 如何在运行例程时将值分配给结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54457213/

相关文章:

xml - 将 XML 文件转换为 CSV

java - 在 Java 中使用线程时维护 FIFO

java - 是否有旨在调试并发软件的 JVM?

go - 为什么内存块没有被垃圾收集器清理?

go - Swagger参数问题

将 slice 限制为最大元素

C++ 条件等待停止执行

multithreading - Goroutines - 为什么我只在最后看到并排执行

http - Golang http 服务器在启动无限循环的 goroutine 时阻塞

go - 停止单个goroutine的最佳方法?