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

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

Golang Data Race,退出狀態(tài)為 66

Golang Data Race,退出狀態(tài)為 66

Go
偶然的你 2022-01-17 17:47:38
我有以下代碼,并且正在進(jìn)行數(shù)據(jù)競爭。Round 函數(shù)定期檢查運(yùn)行刪除地圖內(nèi)容的函數(shù)正如我在這里讀到的:從地圖中刪除數(shù)據(jù)是安全的,但我有數(shù)據(jù)競爭package mainimport (    "fmt"    "sync"    "time")type City struct {    ID string}type Map struct {    sync.RWMutex    Data map[string]City}var done = make(chan struct{})func (m *Map) Round() {    for {        select {        case <-time.After(2 * time.Second):            for i, v := range m.Data {                fmt.Println("-----", v)                delete(m.Data, i)            }        case <-done:            println("bye")            break        }    }}func (m *Map) Add(id string, h City) {    m.Lock()    m.Data[id] = h    m.Unlock()}func main() {    m := Map{}    m.Data = make(map[string]City)    m.Data["Ottowa"] = City{"Canada"}    m.Data["London"] = City{"GB"}    m.Data["malafya"] = City{"malafya"}    go m.Round()    for i := 0; i < 4; i++ {        go func() {            time.Sleep(2 * time.Second)            go m.Add("uz", City{"CityMakon"})            go m.Add("uzb", City{"CityMakon"})        }()    }    time.Sleep(5 * time.Second)    done <- struct{}{}}輸出:----- {Canada}----- {GB}----- {malafya}==================WARNING: DATA RACEWrite by goroutine 12:  runtime.mapassign1()      /usr/lib/golang/src/runtime/hashmap.go:411 +0x0  main.(*Map).Add()      /home/narkoz/elixir/round.go:37 +0xaaPrevious write by goroutine 6:  runtime.mapdelete()      /usr/lib/golang/src/runtime/hashmap.go:511 +0x0  main.(*Map).Round()      /home/narkoz/elixir/round.go:26 +0x3a9Goroutine 12 (running) created at:  main.main.func1()      /home/narkoz/elixir/round.go:54 +0x8cGoroutine 6 (running) created at:  main.main()      /home/narkoz/elixir/round.go:49 +0x2af==================----- {CityMakon}----- {CityMakon}Found 1 data race(s)exit status 66但是當(dāng)我將映射的值類型更改為 int 或 string 時(shí),沒有數(shù)據(jù)競爭。您推薦什么解決方案?
查看完整描述

1 回答

?
12345678_0001

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超5個(gè)贊

更新:


但是當(dāng)我將映射的值類型更改為 int 或 string 時(shí),沒有數(shù)據(jù)競爭。


我進(jìn)一步測試了你的代碼。將映射的值類型更改為 int 或 string 會(huì)繼續(xù)產(chǎn)生競爭條件。嘗試while在你的 shell 上循環(huán)運(yùn)行它,你會(huì)明白我的意思:


$ while true; do go run -race main.go; done

值類型之間不應(yīng)該有任何差異。


正如競態(tài)檢測器所報(bào)告的,有兩種不同的競態(tài)條件。第一場比賽(您已修復(fù))發(fā)生在i第 54 行的讀取 (of ) 和第i51 行的寫入 (to ) 之間。發(fā)生這種情況是因?yàn)槟?goroutine 閉包包含對(duì) 的引用,該引用由goroutine中的循環(huán)i更改. 您可以通過擺脫或傳遞給您的閉包來解決它,如下所示:formainprintln(">>", i)i


for i := 0; i < 4; i++ {

  go func(index int) {

    time.Sleep(2 * time.Second)

    println(">>", index)

    go m.Add("uz", City{"CityMakon"})

    go m.Add("uzb", City{"CityMakon"})

  }(i)

}

第二個(gè)競爭條件發(fā)生在第 37 行 ( m.Data[id] = h) 的賦值和第 25 行 ( ) 的刪除之間delete(m.Data, i)。競態(tài)檢測器將此標(biāo)記為競態(tài)條件,因?yàn)樗荒鼙WC您的代碼上的Happen Before約束。您可以通過以下任一方式解決此問題:


鎖定delete語句:


m.Lock()

delete(m.Data, i)

m.Unlock()

或者,將Round()方法中的兩種情況提取為兩種方法,覆蓋通道:


func (m *Map) Round() {

  for i, v := range m.Data {

    fmt.Println("-----", v)

    delete(m.Data, i)

  }

}


func (m *Map) Done() {

  for range done {

    println("bye")

    break

  }

}


func main() {

  // ...

  go Round()

  go Done()

}


查看完整回答
反對(duì) 回復(fù) 2022-01-17
  • 1 回答
  • 0 關(guān)注
  • 258 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)