校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁(yè) > 知識(shí)庫(kù) > Golang并發(fā)操作中常見(jiàn)的讀寫鎖詳析

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

熱門標(biāo)簽:400手機(jī)電話免費(fèi)辦理 百度地圖標(biāo)注位置網(wǎng)站 開通400電話申請(qǐng)流程 武漢百應(yīng)人工智能電銷機(jī)器人 如何利用高德地圖標(biāo)注家 智能語(yǔ)音電銷的機(jī)器人 揚(yáng)州電銷外呼系統(tǒng)軟件 電腦外呼系統(tǒng)輻射大嗎 上海企業(yè)外呼系統(tǒng)排名

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

golang讀寫鎖,其特征在于

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

讀寫鎖有兩種模式。沒(méi)錯(cuò)!一種是讀模式,一種是寫模式。當(dāng)他為寫模式的話,作用和互斥鎖差不多,只允許有一個(gè)協(xié)程搶到這把鎖,其他協(xié)程乖乖排隊(duì)。但是讀模式就不一樣了,他允許你多個(gè)協(xié)程讀,但是不能寫。總結(jié)起來(lái)就是:

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

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

下面看個(gè)例子吧:

先看主函數(shù):

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

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

在來(lái)看一看寫函數(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()
}

這個(gè)Lock()就是執(zhí)行讀寫鎖的寫模式,當(dāng)這個(gè)模式進(jìn)行時(shí),只有這條協(xié)程能寫,其他協(xié)程都被阻塞。Unlock()就是解鎖這個(gè)僅鎖模式,等待組中的其他協(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í)行這個(gè)模式其他協(xié)程也能讀,但是都不能寫。

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

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

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

Golang讀寫鎖底層原理

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

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

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

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

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

總結(jié)

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

標(biāo)簽:宜賓 黑龍江 張掖 新余 嘉峪關(guān) 江西 武漢 延邊

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Golang并發(fā)操作中常見(jiàn)的讀寫鎖詳析》,本文關(guān)鍵詞  Golang,并發(fā),操作,中,常見(jiàn),;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Golang并發(fā)操作中常見(jiàn)的讀寫鎖詳析》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于Golang并發(fā)操作中常見(jiàn)的讀寫鎖詳析的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    主站蜘蛛池模板: 长岭县| 高邮市| 鄄城县| 富锦市| 定兴县| 大港区| 昌图县| 开鲁县| 灵璧县| 安顺市| 沂南县| 黑山县| 泉州市| 伊吾县| 当涂县| 建平县| 依兰县| 大洼县| 揭东县| 射洪县| 平阳县| 岳普湖县| 芦山县| 马关县| 台东市| 葫芦岛市| 浮山县| 和田市| 西安市| 乌什县| 日土县| 岳池县| 延庆县| 上犹县| 九台市| 寻甸| 和平区| 仁怀市| 资阳市| 临西县| 玉田县|