中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Golang并發操作中讀寫鎖的示例分析

發布時間:2021-08-30 09:23:13 來源:億速云 閱讀:140 作者:小新 欄目:開發技術

這篇文章主要介紹Golang并發操作中讀寫鎖的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

golang讀寫鎖,其特征在于

  • 讀鎖:可以同時進行多個協程讀操作,不允許寫操作

  • 寫鎖:只允許同時有一個協程進行寫操作,不允許其他寫操作和讀操作

讀寫鎖有兩種模式。沒錯!一種是讀模式,一種是寫模式。當他為寫模式的話,作用和互斥鎖差不多,只允許有一個協程搶到這把鎖,其他協程乖乖排隊。但是讀模式就不一樣了,他允許你多個協程讀,但是不能寫。總結起來就是:

  • 僅讀模式: 多協程可讀不可寫

  • 僅寫模式: 單協程可寫不可讀

在32位的操作系統中,針對int64類型的值的讀和寫操作都不可能僅由一個CPU指令來完成。如若一個寫操作剛剛執行完第一個指令,就去進行另一個讀的協程,這樣就會讀到一個錯誤的數據。

下面看個例子吧:

先看主函數:

func main() {
    for i:=0;i<5;i++{
        wg06.Add(1)
        go write(i)

        wg06.Add(1)
        go read(i)
    }
    wg06.Wait()
}

每次開辟兩條協程,一條協程執行寫函數,另一條執行讀函數。然后放入等待組。共開辟五次。

在來看一看寫函數

func write(i int)  {
    //鎖定為僅寫模式,其他協程被阻塞
    rwm.Lock()

    fmt.Println(i,"writing...")
    <- time.After(10*time.Second)
    fmt.Println("write over!")

    rwm.Unlock()
    //解鎖僅寫模式
    wg06.Done()
}

這個Lock()就是執行讀寫鎖的寫模式,當這個模式進行時,只有這條協程能寫,其他協程都被阻塞。Unlock()就是解鎖這個僅鎖模式,等待組中的其他協程不再被阻塞。

再看一看讀模式:

func read(i int)  {
    rwm.RLock()

    fmt.Println(i,"reading...")
    <-time.After(10 * time.Second)
    fmt.Println(i,"read over!")

    rwm.RUnlock()
    wg06.Done()
}

RLock()就是執行讀寫鎖的讀模式,執行這個模式其他協程也能讀,但是都不能寫。

如果程序運行,寫協程先搶到鎖,所有協程就不能讀,只有這條寫協程能寫,其他人都等著。如果是讀協程搶到鎖,所以寫協程就不可能了,但是讀協程仍然可以搶。

現在你知道我們應該什么時候使用讀寫鎖了嗎?

在并發進行讀寫操作時,當讀的次數遠遠超過寫的次數的情況下,應該使用讀寫鎖來進行讀寫并發操作。

Golang讀寫鎖底層原理

在加讀鎖和寫鎖的工程中都使用atomic.AddInt32來進行遞增,而該指令在底層是會通過LOCK來進行CPU總線加鎖的,因此多個CPU同時執行readerCount其實只會有一個成功,從這上面看其實是寫鎖與讀鎖之間是相對公平的,誰先達到誰先被CPU調度執行,進行LOCK鎖cache line成功,誰就加成功鎖

底層實現的CPU指令

底層的2條指令,通過LOCK指令配合CPU的MESI協議,實現可見性和內存屏障,同時通過XADDL則用來保證原子性,從而解決可見性與原子性問題

// atomic/asm_amd64.s TEXT runtime∕internal∕atomic·Xadd(SB)
    LOCK
    XADDL   AX, 0(BX)

可見性與內存屏障、原子性, 其中可見性通常是指在cpu多級緩存下如何保證緩存的一致性,即在一個CPU上修改了了某個數據在其他的CPU上不會繼續讀取舊的數據,內存屏障通常是為了CPU為了提高流水線性能,而對指令進行重排序而來,而原子性則是指的執行某個操作的過程的不可分割

以上是“Golang并發操作中讀寫鎖的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

潞西市| 蒙自县| 德安县| 大安市| 陕西省| 玛沁县| 迭部县| 德阳市| 会泽县| 蕲春县| 大安市| 通海县| 平和县| 鄯善县| 五大连池市| 汝阳县| 景谷| 桦川县| 新闻| 江山市| 汝南县| 西畴县| 古田县| 霞浦县| 互助| 巴林右旗| 如东县| 盐津县| 余干县| 平乡县| 札达县| 许昌市| 和顺县| 开平市| 阿拉善左旗| 阳泉市| 湘潭县| 达拉特旗| 田林县| 铁岭县| 固始县|