2 回答
TA贡献1816条经验 获得超6个赞
您锁定调用并设置了一个功能,它也锁定了。viperLockvipe.WatchConfig()vipe.OnConfigChangeviperLock
因为你已经打过电话,然后它开始打电话给单独的go例程。它也试图获取相同的锁。这就是存在争用条件的原因。vipe.WatchConfig()vipe.OnConfigChange
在设置后和释放锁后调用。vipe.WatchConfig()vipe.OnConfigChange
应按如下方式更正。
func loadConfigDynamically() {
go func() {
time.Sleep(time.Second)
viperLock.Lock()
vipe.OnConfigChange(func(e fsnotify.Event) {
viperLock.Lock()
log.Println("config file changed", e.Name)
environment := vipe.GetString("env")
reloadConfig <- environment
viperLock.Unlock()
})
viperLock.Unlock()
vipe.WatchConfig() //this starting call vipe.OnConfigChange
}()
}
TA贡献1862条经验 获得超7个赞
可能是 go 认为变量正在同时被两个 goroutine 修改和访问,并且修改和访问的位置没有锁定。类似于以下示例:
package main
import (
"time"
)
type Foo struct {
f func(string)
}
func (f *Foo) Watch() {
go func() {
for {
time.Sleep(time.Second * 2)
if f.f != nil {
f.f("hello world")
}
}
}()
}
func (f *Foo) SetF(fun func(string)) {
f.f = fun
}
func main() {
f := Foo{}
f.Watch()
f.SetF(func(s string) {
})
time.Sleep(time.Second * 5)
}
它有一场数据竞赛。如果我在修改和读取的地方都放了相同的锁,就不会有数据竞争:
package main
import (
"sync"
"time"
)
var lock sync.Mutex
type Foo struct {
f func(string)
}
func (f *Foo) Watch() {
go func() {
for {
time.Sleep(time.Second * 2)
lock.Lock() // read places
if f.f != nil {
f.f("hello world")
}
lock.Unlock()
}
}()
}
func (f *Foo) SetF(fun func(string)) {
f.f = fun
}
func main() {
f := Foo{}
f.Watch()
lock.Lock() // write places
f.SetF(func(s string) {
})
lock.Unlock()
time.Sleep(time.Second * 5)
}
或者消除两个哥律同时阅读和写入的可能性会很好:
func main() {
f := Foo{}
f.SetF(func(s string) {
})
f.Watch()
time.Sleep(time.Second * 5)
}
- 2 回答
- 0 关注
- 77 浏览
添加回答
举报