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

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

此代碼片段如何成為錯誤同步的示例?

此代碼片段如何成為錯誤同步的示例?

Go
慕村9548890 2022-09-05 17:28:54
我試圖用來自The Go Memory Model的錯誤同步代碼來理解這個例子。雙重檢查鎖定是避免同步開銷的嘗試。例如,twoprint 程序可能被錯誤地編寫為:var a stringvar done boolfunc setup() {    a = "hello, world"    done = true}func doprint() {    if !done {        once.Do(setup)    }    print(a)}func twoprint() {    go doprint()    go doprint()}但是不能保證,在 中,觀察要完成的寫入意味著觀察寫入 。此版本可以(錯誤地)打印空字符串而不是 。doprinta"hello, world"用空字符串代替“hello world”的詳細(xì)原因是什么?我運行了大約五次這段代碼,每次都打印了“hello world”。編譯器是否會交換一行并進(jìn)行優(yōu)化?只有在這種情況下,我才能理解為什么會打印一個空字符串。a = "hello, world"done = true多謝!在底部,我附加了測試的更改代碼。package mainimport("fmt""sync")var a stringvar done boolvar on sync.Oncefunc setup() {    a = "hello, world"    done = true}func doprint() {    if !done {        on.Do(setup)    }    fmt.Println(a)}func main() {    go doprint()    go doprint()    select{}}
查看完整描述

3 回答

?
吃雞游戲

TA貢獻(xiàn)1829條經(jīng)驗 獲得超7個贊

根據(jù)Go內(nèi)存模型:

https://golang.org/ref/mem

不能保證一個 goroutine 會看到另一個 goroutine 執(zhí)行的操作,除非兩者之間使用通道互斥體進(jìn)行顯式同步。等。

在你的例子中:一個 goroutines 看到的事實并不意味著它會看到 set。僅當(dāng) goroutines 之間存在顯式同步時,才能保證這一點。done=truea

可能提供這樣的同步,所以這就是為什么你沒有觀察到這種行為。仍然有一場內(nèi)存競賽,在不同的平臺上,有不同的實現(xiàn),事情可能會發(fā)生變化。sync.Oncesync.Once


查看完整回答
反對 回復(fù) 2022-09-05
?
繁星淼淼

TA貢獻(xiàn)1775條經(jīng)驗 獲得超11個贊

有關(guān) Go Memory 模型的參考頁面會告訴您以下內(nèi)容:


編譯器和處理器可以對在單個 goroutine 中執(zhí)行的讀取和寫入進(jìn)行重新排序,前提是重新排序不會更改語言規(guī)范所定義的 goroutine 中的行為。


因此,編譯器可以在函數(shù)體內(nèi)對兩次寫入重新排序,從setup


a = "hello, world"

done = true


done = true

a = "hello, world"

然后可能會出現(xiàn)以下情況:


一個 goroutine 不觀察寫入,因此啟動函數(shù)的單次執(zhí)行;doprintdonesetup

另一個 goroutine 觀察寫入 ,但在觀察寫入之前完成執(zhí)行 ;因此,它打印 類型的零值,即空字符串。doPrintdoneaa

我運行了大約五次這段代碼,每次都打印了“hello world”。


您需要了解同步錯誤(代碼的屬性)和爭用條件(特定執(zhí)行的屬性)之間的區(qū)別;Valentin Deleplace的這篇文章在闡明這種區(qū)別方面做得很好。簡而言之,同步錯誤可能會也可能不會引起爭用條件;但是,僅僅因為爭用條件不會在程序的多次執(zhí)行中表現(xiàn)出來,并不意味著您的程序沒有錯誤。


在這里,您可以“強制”爭用條件發(fā)生,只需對兩個寫入進(jìn)行重新排序并在兩者之間添加一個微小的睡眠即可。setup


func setup() {

    done = true

    time.Sleep(1 * time.Millisecond)

    a = "hello, world"

}


這可能足以說服您該程序確實包含同步錯誤。


查看完整回答
反對 回復(fù) 2022-09-05
?
呼如林

TA貢獻(xiàn)1798條經(jīng)驗 獲得超3個贊

該程序不是內(nèi)存安全的,因為:

  • 多個 goroutine 同時訪問同一內(nèi)存 ( 和 )。donea

  • 并發(fā)訪問并不總是由顯式同步控制。

  • 訪問可以寫入/修改內(nèi)存。

試圖推理程序在這些變量方面將如何表現(xiàn)或不將如何表現(xiàn)可能只是不必要的混淆,因為它實際上是未定義的行為。沒有“正確”的答案。只有間接觀察,它們不能硬保證它們是否或何時成立。


查看完整回答
反對 回復(fù) 2022-09-05
  • 3 回答
  • 0 關(guān)注
  • 151 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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