Go語言 之讀寫鎖


package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

//全局變量
var count int
var rLock sync.RWMutex

func Read(i int) {
    rLock.RLock()
    fmt.Printf("讀 goroutine%d 數據=%d\n", i, count)
    defer rLock.RUnlock()
}

func Write(i int) {
    rLock.Lock()
    count = rand.Intn(1000)
    fmt.Printf("寫 goroutine%d 數據=%d\n", i, count)
    defer rLock.Unlock()
}

func main() {
    for i := 0; i < 5; i++ {
        go Write(i)
    }
    for i := 0; i < 5; i++ {
        go Read(i)
    }
    time.Sleep(time.Second * 2)
    //執行結果:
    /*
        寫 goroutine0 數據=81
        寫 goroutine1 數據=887
        讀 goroutine1 數據=887
        寫 goroutine3 數據=847
        寫 goroutine4 數據=59
        讀 goroutine0 數據=59
        讀 goroutine3 數據=59
        寫 goroutine2 數據=81
        讀 goroutine4 數據=81
        讀 goroutine2 數據=81
    */
}

互斥鎖的本質是當一個goroutine訪問的時候,其他goroutine都不能訪問。這樣在資源同步,避免競爭的同時也降低了程序的並發性能。程序由原來的並行執行變成了串行執行。

其實,當我們對一個不會變化的數據只做“讀”操作的話,是不存在資源競爭的問題的。因為數據是不變的,不管怎么讀取,多少goroutine同時讀取,都是可以的。

所以問題不是出在“讀”上,主要是修改,也就是“寫”。修改的數據要同步,這樣其他goroutine才可以感知到。所以真正的互斥應該是讀取和修改、修改和修改之間,讀和讀是沒有互斥操作的必要的。

因此,衍生出另外一種鎖,叫做讀寫鎖。

讀寫鎖可以讓多個讀操作並發,同時讀取,但是對於寫操作是完全互斥的。也就是說,當一個goroutine進行寫操作的時候,其他goroutine既不能進行讀操作,也不能進行寫操作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM