我有两个结构App
和Config
。
type App struct {
cfg Config
}
type Config struct {
dbHost string
dbPort int
user string
password string
}
以及在App上定义的两种更新和读取CCD_ 3字段的方法。
func (app *App) UpdateConfig(newCfg Config) {
app.cfg = newCfg
}
func (app *App) GetConfig() Config {
return app.cfg
}
如果只有一个goroutine正在调用UpdateConfig
,而多个goroutines正在通过GetConfig
方法读取配置,那么我应该用互斥来保护对app.cfg
的访问吗?
编辑:阅读器goroutines正在for循环中调用GetConfig
。不需要"立即"看到配置的更新值。读者可以在下一次迭代中看到cfg的更新值。
所以我重新表述我的问题:读者有可能看到部分更新的配置值吗?
不,如果异步修改,则不应该期望看到全部或全部更新的配置。
Go努力做到合理(即使它没有正式保证(;如果你在一个不能撕毁字大小更新的体系结构上更新一个字大小的对象,那么即使你不同步,你也会看到更新或看不到。(这与C和C++不同,在C和C++中,未定义的行为意味着编译器可以合法地执行任何操作(。但在这里,Config
是一个很大的值,并且没有任何廉价的方法可以保证您想要的全部或全部更新(而不执行一些同步本身(。
但是,是的,您应该使用互斥锁来保护配置。如果有太多的争论,并且您一点也不介意旧的配置,那么您可以定期轮询官方配置,并在其更改时更新本地副本。
实际上,互斥锁很快,即使速度稍慢,也最好有异步正确的代码。例如,如果您没有异步正确的代码,那么即使您的代码按照您的意愿运行,也无法轻松使用种族检测器来查找其他真正的问题。