最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang并發(fā)操作中常見的讀寫鎖詳析

 更新時間:2021年08月29日 11:43:23   作者:ReganYue  
Golang中的鎖機(jī)制主要包含互斥鎖和讀寫鎖互斥鎖互斥鎖是傳統(tǒng)并發(fā)程序?qū)蚕碣Y源進(jìn)行控制訪問的主要手段,這篇文章主要給大家介紹了關(guān)于Golang并發(fā)操作中常見的讀寫鎖的相關(guān)資料,需要的朋友可以參考下

互斥鎖簡單粗暴,誰拿到誰操作。今天給大家介紹一下讀寫鎖,讀寫鎖比互斥鎖略微復(fù)雜一些,不過我相信我們今天能夠把他拿下!

golang讀寫鎖,其特征在于

  • 讀鎖:可以同時進(jìn)行多個協(xié)程讀操作,不允許寫操作
  • 寫鎖:只允許同時有一個協(xié)程進(jìn)行寫操作,不允許其他寫操作和讀操作

讀寫鎖有兩種模式。沒錯!一種是讀模式,一種是寫模式。當(dāng)他為寫模式的話,作用和互斥鎖差不多,只允許有一個協(xié)程搶到這把鎖,其他協(xié)程乖乖排隊。但是讀模式就不一樣了,他允許你多個協(xié)程讀,但是不能寫??偨Y(jié)起來就是:

  • 僅讀模式: 多協(xié)程可讀不可寫
  • 僅寫模式: 單協(xié)程可寫不可讀

在32位的操作系統(tǒng)中,針對int64類型的值的讀和寫操作都不可能僅由一個CPU指令來完成。如若一個寫操作剛剛執(zhí)行完第一個指令,就去進(jìn)行另一個讀的協(xié)程,這樣就會讀到一個錯誤的數(shù)據(jù)。

下面看個例子吧:

先看主函數(shù):

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

每次開辟兩條協(xié)程,一條協(xié)程執(zhí)行寫函數(shù),另一條執(zhí)行讀函數(shù)。然后放入等待組。共開辟五次。

在來看一看寫函數(shù)

func write(i int)  {
    //鎖定為僅寫模式,其他協(xié)程被阻塞
    rwm.Lock()
​
    fmt.Println(i,"writing...")
    <- time.After(10*time.Second)
    fmt.Println("write over!")
​
    rwm.Unlock()
    //解鎖僅寫模式
    wg06.Done()
}

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

再看一看讀模式:

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()就是執(zhí)行讀寫鎖的讀模式,執(zhí)行這個模式其他協(xié)程也能讀,但是都不能寫。

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

現(xiàn)在你知道我們應(yīng)該什么時候使用讀寫鎖了嗎?

在并發(fā)進(jìn)行讀寫操作時,當(dāng)讀的次數(shù)遠(yuǎn)遠(yuǎn)超過寫的次數(shù)的情況下,應(yīng)該使用讀寫鎖來進(jìn)行讀寫并發(fā)操作。

Golang讀寫鎖底層原理

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

底層實現(xiàn)的CPU指令

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

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

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

總結(jié)

到此這篇關(guān)于Golang并發(fā)操作中常見讀寫鎖的文章就介紹到這了,更多相關(guān)Golang并發(fā)讀寫鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go 中閉包的底層原理

    Go 中閉包的底層原理

    這篇文章主要介紹了Go 中閉包的底層原理,閉包的基本原理是一種現(xiàn)象,一個函數(shù)內(nèi)引用了外部的局部變量的現(xiàn)象,帶著些許的了解和小編一起進(jìn)入文章正題學(xué)習(xí)
    2021-10-10
  • Go語言編程通過dwarf獲取內(nèi)聯(lián)函數(shù)

    Go語言編程通過dwarf獲取內(nèi)聯(lián)函數(shù)

    這篇文章主要為大家介紹了Go語言編程通過dwarf獲取內(nèi)聯(lián)函數(shù)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Go中使用加密算法的方法

    Go中使用加密算法的方法

    本文通過實例代碼給大家介紹go中使用加密算法的方法,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-08-08
  • Go使用chan或context退出協(xié)程示例詳解

    Go使用chan或context退出協(xié)程示例詳解

    這篇文章主要為大家介紹了Go使用chan或context退出協(xié)程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Golang結(jié)合ip2region實現(xiàn)ip歸屬地查詢

    Golang結(jié)合ip2region實現(xiàn)ip歸屬地查詢

    ip2region - 是一個離線IP地址定位庫和IP定位數(shù)據(jù)管理框架,提供了眾多主流編程語言的 xdb 數(shù)據(jù)生成和查詢客戶端實現(xiàn),下面我們就來看看Golang如何結(jié)合ip2region實現(xiàn)ip歸屬地查詢吧
    2024-03-03
  • Go使用XORM操作MySQL的陷阱盤點分析

    Go使用XORM操作MySQL的陷阱盤點分析

    在?Go?語言開發(fā)中,大家為了方便,通常會選擇使用?ORM?操作數(shù)據(jù)庫,比如使用?XORM?或?GORM?操作?MySQL,本文我們來介紹一下使用?XORM[3]?操作?MySQL?可能會遇到的陷阱
    2023-11-11
  • Go語言同步與異步執(zhí)行多個任務(wù)封裝詳解(Runner和RunnerAsync)

    Go語言同步與異步執(zhí)行多個任務(wù)封裝詳解(Runner和RunnerAsync)

    這篇文章主要給大家介紹了關(guān)于Go語言同步與異步執(zhí)行多個任務(wù)封裝(Runner和RunnerAsync)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • golang實戰(zhàn)之truncate日志文件詳解

    golang實戰(zhàn)之truncate日志文件詳解

    這篇文章主要給大家介紹了關(guān)于golang實戰(zhàn)之truncate日志文件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • 詳解Go語言如何對數(shù)據(jù)庫進(jìn)行CRUD操作

    詳解Go語言如何對數(shù)據(jù)庫進(jìn)行CRUD操作

    在這篇文章中,主要帶大家來學(xué)習(xí)一下在Go語言中如何對數(shù)據(jù)庫進(jìn)行CRUD操作,從而探討一下Go的接口編程,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-05-05
  • 如何使用proto組件編譯pb.go文件

    如何使用proto組件編譯pb.go文件

    這篇文章主要介紹了如何使用proto組件編譯pb.go文件的詳細(xì)過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10

最新評論

广元市| 祁门县| 潜山县| 淄博市| 新河县| 德令哈市| 闻喜县| 竹北市| 阿克陶县| 汪清县| 洛宁县| 含山县| 宝丰县| 辽中县| 彰武县| 古交市| 容城县| 临高县| 南阳市| 桓台县| 城固县| 万盛区| 乐至县| 贵溪市| 湟中县| 越西县| 永修县| 大厂| 嘉荫县| 新竹县| 扎赉特旗| 潮州市| 深泽县| 长沙县| 集安市| 榆中县| 德安县| 辽阳县| 孟州市| 镇沅| 岢岚县|