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

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

使用 WaitGroup 測試競爭條件時的意外行為

使用 WaitGroup 測試競爭條件時的意外行為

Go
慕村9548890 2023-05-15 15:37:22
我的任務是在 Go 中模擬競爭條件。但是,我遇到了一個我無法解釋的案例。下面的代碼片段package mainimport (    "fmt"    "sync")var value, totalOps, totalIncOps, totalDecOps intfunc main() {    fmt.Println("Total value: ", simulateRacing(10000))    fmt.Print("Total iterations: ", totalOps)    fmt.Print(" of it, increments: ", totalIncOps)    fmt.Print(", decrements: ", totalDecOps)}// Function to simulate racing conditionfunc simulateRacing(iterationsNumber int) int {    value = 0    // Define WaitGroup    var waitGroup sync.WaitGroup    waitGroup.Add(2)    go increaseByOne(iterationsNumber, &waitGroup)    go decreaseByOne(iterationsNumber, &waitGroup)    waitGroup.Wait()    return value}// Function to do N iterations, each time increasing value by 1func increaseByOne(N int, waitGroup *sync.WaitGroup) {    for i := 0; i < N; i++ {        value++        // Collecting stats        totalOps++        totalIncOps++    }    waitGroup.Done()}// Same with decreasefunc decreaseByOne(N int, waitGroup *sync.WaitGroup) {    for i := 0; i < N; i++ {        value--        // Collecting stats        totalOps++        totalDecOps++    }    waitGroup.Done()}以我的理解,它應該每次都產生一致的(確定性的)結果,因為我們正在執(zhí)行相同數(shù)量的遞增和遞減,WaitGroup 確保兩個函數(shù)都將執(zhí)行。但是,每次輸出都不同,只有遞增和遞減計數(shù)器保持不變。 總值:2113 總迭代:17738 次,增量:10000,減量:10000 和 總值:35 總迭代:10741 次,增量:10000,減量:10000也許你能幫我解釋一下這種行為?為什么總迭代計數(shù)器和值本身是不確定的?
查看完整描述

2 回答

?
慕標琳琳

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

這是競爭條件的經(jīng)典例子。value++不是原子操作,因此無法保證在沒有同步的情況下從多個線程調用時它會正確或確定地工作。

給出一些直覺,value++或多或少等同于value = value + 1. 您可以將其視為三個操作,而不是一個:value從內存加載到 CPU 寄存器,增加寄存器中的值(您不能直接修改內存),將值存儲回內存。兩個線程可能同時加載相同的值,增加它,得到相同的結果,然后將它寫回,所以它實際上增加了value1,而不是兩個。

由于線程之間的操作順序是不確定的,因此結果也是不確定的。

同樣的效果發(fā)生在totalOps. 但是,totalIncOpstotalDecOps只能由單個線程修改/讀取,因此這里沒有競爭,它們的最終值是確定性的。


查看完整回答
反對 回復 2023-05-15
?
弒天下

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

因為對變量 value、totalOps、totalIncOps 和 totalDecOps 的操作沒有被鎖定


添加互斥鎖應該有所幫助。Go race detector 功能會發(fā)現(xiàn)這個錯誤


var m sync.Mutex


func increaseByOne(N int, waitGroup *sync.WaitGroup) {

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

        m.Lock()

value++

        // Collecting stats

        totalOps++

        totalIncOps++

        m.Unlock()

    }

    waitGroup.Done()

}


// Same with decrease

func decreaseByOne(N int, waitGroup *sync.WaitGroup) {

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

        m.Lock()

        value--

        // Collecting stats

        totalOps++

        totalDecOps++

        m.Unlock()

    }

    waitGroup.Done()

}

上述方法的替代方法是對計數(shù)器使用 Sync.Atomic


查看完整回答
反對 回復 2023-05-15
  • 2 回答
  • 0 關注
  • 171 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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