第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

蝰蛇動態(tài)加載配置文件有數(shù)據(jù)賽跑

蝰蛇動態(tài)加載配置文件有數(shù)據(jù)賽跑

Go
SMILET 2022-09-26 15:49:49
我想動態(tài)加載配置文件,而不是重新啟動我的Go應用程序。我寫了下面的文件,這些文件可以運行,但有數(shù)據(jù)競爭。配置.gopackage mainimport (    "github.com/fsnotify/fsnotify"    "github.com/spf13/viper"    "log"    "sync"    "time")var (    reloadConfig  = make(chan string)    reloadConfig2 = make(chan string)    viperLock1    sync.Mutex    viperLock2    sync.Mutex)func setUpConfig(file string, merge bool, v *viper.Viper) {    v.AddConfigPath("./")    v.SetConfigName(file)    v.SetConfigType("yml")    if merge {        err1 := v.MergeInConfig()        checkForFatalError("fatal error occurred while reading config file!", err1)    } else {        err := v.ReadInConfig()        checkForFatalError("fatal error occurred while reading config file!", err)    }    log.Println("Initial config value: ", v.GetString("env"))}func loadConfigDynamically(configChannel chan string, viperLock *sync.Mutex, vipe *viper.Viper) {    viperLock.Lock()    vipe.OnConfigChange(func(e fsnotify.Event) {        viperLock.Lock()        log.Println("config file changed", e.Name)        environment := vipe.GetString("env")        configChannel <- environment        viperLock.Unlock()    })    viperLock.Unlock()    vipe.WatchConfig()}func loadMultipleConfigsDynamically() {    go func() {        time.Sleep(time.Millisecond * 50)        vipe2 := viper.New()        setUpConfig("config_base", false, vipe2)        loadConfigDynamically(reloadConfig2, &viperLock2, vipe2)        time.Sleep(time.Millisecond * 50)        vipe1 := viper.New()        setUpConfig("config", false, vipe1)        loadConfigDynamically(reloadConfig, &viperLock1, vipe1)    }()}主要.gopackage mainimport (    log "github.com/sirupsen/logrus"    "os"    "os/signal"    "syscall")var reloadConfigNow = make(chan bool)var reloadConfigAgain = make(chan bool)var newConfigValue stringfunc main() {    loadMultipleConfigsDynamically()    go printUpdatedValueOnly()    go justAnotherGoroutine()    go yetAnotherGoroutine()    shutdownAppGracefully()}
查看完整描述

2 回答

?
瀟湘沐

TA貢獻1816條經(jīng)驗 獲得超6個贊

您鎖定調(diào)用并設置了一個功能,它也鎖定了。viperLockvipe.WatchConfig()vipe.OnConfigChangeviperLock


因為你已經(jīng)打過電話,然后它開始打電話給單獨的go例程。它也試圖獲取相同的鎖。這就是存在爭用條件的原因。vipe.WatchConfig()vipe.OnConfigChange


在設置后和釋放鎖后調(diào)用。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

    }()

}


查看完整回答
反對 回復 2022-09-26
?
牧羊人nacy

TA貢獻1862條經(jīng)驗 獲得超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)

}

它有一場數(shù)據(jù)競賽。如果我在修改和讀取的地方都放了相同的鎖,就不會有數(shù)據(jù)競爭:


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)

}


查看完整回答
反對 回復 2022-09-26
  • 2 回答
  • 0 關注
  • 94 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號