go - 是在赋值给结构原子吗?

标签 go

我有两个结构AppConfig

type App struct {
    cfg Config
}

type Config struct {
    dbHost   string
    dbPort   int
    user     string
    password string
}

和在App上定义的两种方法来更新和读取cfg字段。

func (app *App) UpdateConfig(newCfg Config) {
    app.cfg = newCfg
}

func (app *App) GetConfig() Config {
    return app.cfg
}

如果只有一个goroutine正在调用UpdateConfig,而多个goroutine正在通过GetConfig方法读取配置,我是否应该使用互斥锁来保护对app.cfg的访问?

编辑:读者goroutine在for循环中调用GetConfig。无需“立即”查看配置的更新值。读者可以在下一次迭代中查看cfg的更新值。

所以我改写我的问题:读者有可能看到部分更新的配置值吗?

最佳答案

不,如果您异步修改更新的配置,则不应期望看到全部或全部。

Go试图做到合理(即使它不能正式保证它);如果您在无法删除单词大小的更新的体系结构上更新单词大小的对象,那么即使您不同步,也将看到或看不到更新。 (这与C和C++不同,在C和C++中,未定义的行为表示编译器可以合法地执行任何操作)。但是在这里,Config是一个很大的值,没有便宜的方法可以保证您想要的全部更新(无需本身执行一些同步)。

但是,是的,您应该使用互斥锁来保护配置。如果存在太多争用,并且您一点也不在乎旧的配置,则可以定期轮询官方配置,并在更改时更新本地副本。

在实用上,互斥锁是快速的,并且拥有异步正确的代码几乎总是更好,即使它稍慢一些。例如,如果您没有异步正确的代码,则即使您的代码表现为所需的行为,也无法轻松地使用竞争检测器来查找其他真正的问题。

关于go - 是在赋值给结构原子吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60820731/

相关文章:

html - 在 Golang 的 HTML 模板中使用 Vue.js

go - 使用 Go Context 包时省略 ctx.Done() 是否安全?

json - Golang 序列化/反序列化一个空数组而不是 null

date - 如何从 civil.Datetime 获取 time.Time

go - 运行前如何通过gin合并多个路由器

dictionary - 测试和处理映射中的多个键的惯用 Go 方式是什么?

go - 在 Golang 中阅读首选 RW 互斥锁

amazon-web-services - 获取 s3 存储桶上的资源 URI

file - 如何在 Go 中的 io.Reader 上测试 EOF?

go - 获取 Go 中传输的连接数