sync.RWMutex 功能的測試

wanna發表於2020-09-15

RWMutex 裡共四個方法

func (rw *RWMutex) Lock() // 寫鎖
func (rw *RWMutex) Unlock() // 寫解鎖

func (rw *RWMutex) RLock() // 讀鎖
func (rw *RWMutex) RUnlock() // 讀解鎖

這裡要著重理解下

  1. 讀鎖不互斥(可以多個一起讀)
  2. 寫鎖互斥(只能有一個在寫入)
  3. 有讀不可寫,有寫不可讀(讀寫不能同時進行)

我使用了兩個方法驗證加讀寫鎖後的安全其中
fun rwMutex(i int) 使用了 RWMutex 鎖,開協程併發的累加到 10000,同時開協程累減到 10000,最終得到的值為 0,證明加鎖後是獨寫安全的
fun rwWithoutMutex(i int) 沒有使用了 RWMutex 鎖,同上一方法先同時累加累減,得到結果不為預期值 0,所以獨寫不安全

程式碼如下

type info struct {
    sync.RWMutex
    data int
}

func rwMutex(count int)  {
    c := make(chan struct{},count * 3)
    l := info{data:0}
    for i := 0; i < count; i++ {
        go func() {
            l.RLock()
            d := l.data
            fmt.Printf("我讀取到了data,值為:%d\n",d)
            l.RUnlock()
            c <- struct{}{}
        }()
    }
    for i := 0; i < count; i++ {
        go func(i int) {
            l.Lock()
            l.data += i
            fmt.Printf("我把data的值加了%d變成了%d\n",i,l.data)
            l.Unlock()
            c <- struct{}{}
        }(i)
    }
    for i := 0; i < count; i++ {
        go func(i int) {
            l.Lock()
            l.data -= i
            fmt.Printf("我把data的值減了%d變成了%d\n",i,l.data)
            l.Unlock()
            c <- struct{}{}
        }(i)
    }
    for i := 0; i < count * 3; i++ {
        <-c
    }
    fmt.Printf("data的最終結果應該為0,實際結果為:%d",l.data)
}

func rwWithoutMutex(count int)  {
    c := make(chan struct{},count * 3)
    l := 0
    for i := 0; i < count; i++ {
        go func() {
            fmt.Printf("我讀取到了data,值為:%d\n",l)
            c <- struct{}{}
        }()
    }
    for i := 0; i < count; i++ {
        go func(i int) {
            l += i
            fmt.Printf("我把data的值加了%d變成了%d\n",i,l)
            c <- struct{}{}
        }(i)
    }
    for i := 0; i < count; i++ {
        go func(i int) {
            l -= i
            fmt.Printf("我把data的值減了%d變成了%d\n",i,l)
            c <- struct{}{}
        }(i)
    }
    for i := 0; i < count * 3; i++ {
        <-c
    }
    fmt.Printf("不安全讀寫時data的最終結果應該為0,實際結果為:%d",l)
}

呼叫 rwMutex(10000) 得到結果

... ...
我把data的值減了9869變成了88935
我把data的值減了9866變成了79069
我把data的值減了9867變成了69202
我把data的值減了9864變成了59338
我把data的值減了9929變成了49409
我把data的值減了9868變成了39541
我把data的值減了9928變成了29613
我把data的值減了9871變成了19742
我把data的值減了9870變成了9872
我把data的值減了9872變成了0
data的最終結果應該為0,實際結果為:0

呼叫 rwWithoutMutex(10000) 得到結果

... ...
我讀取到了data,值為:0
我讀取到了data,值為:0
我讀取到了data,值為:0
我把data的值加了175變成了-30536
我把data的值加了1410變成了-30536
我讀取到了data,值為:0
我把data的值加了811變成了-356884
我讀取到了data,值為:0
我讀取到了data,值為:0
不安全讀寫時data的最終結果應該為0,實際結果為:-30536
更多原創文章乾貨分享,請關注公眾號
  • sync.RWMutex 功能的測試
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章