1. 程式人生 > 其它 >十三. Go學習:鎖機制

十三. Go學習:鎖機制

技術標籤:Golang學習總結golang

執行緒同步時,可能會有多個執行緒需要使用這個資源,為了避免資源競爭,我們需要鎖機制。

1. import("sync")

2. 互斥鎖,var mu sync.Mutex

2. 讀寫所, var mu sync.RWMutex

互斥鎖

package main

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

var lock sync.Mutex

func testMap() {
	var a map[int]int
	a = make(map[int]int, 5)

	a[8] = 10
	a[3] = 10
	a[2] = 10
	a[1] = 10
	a[18] = 10
	//互斥鎖,一次只能進一個
	for i := 0; i < 2; i++ {
		go func(b map[int]int) {
			lock.Lock()
			b[8] = rand.Intn(100)
			lock.Unlock()
		}(a)
	}
	lock.Lock()
	fmt.Println(a)
	lock.Unlock()
}
func main(){
    testMap()
}

讀寫鎖

適合讀多寫少的情景。

程式碼範例如下。結果顯示共計數81601次,而如果用互斥鎖僅僅能計數814次。

package main

import (
	"fmt"
	"math/rand"
	"sync"
	"sync/atomic" //原子操作,用於gorounte計數
	"time"
)

var lock sync.Mutex
var rwLock sync.RWMutex

func testRWLock() {
	var a map[int]int
	a = make(map[int]int, 5)
	var count int32
	//讀寫鎖,讀者只對共享資源進行讀訪問,寫著則需要對共享資源進行寫操作
	a[8] = 10
	a[3] = 10
	a[2] = 10
	a[1] = 10
	a[18] = 10
	for i := 0; i < 2; i++ {
		go func(b map[int]int) {
			rwLock.Lock()
			b[8] = rand.Intn(100)
			rwLock.Unlock()
		}(a)
	}
		go func(b map[int]int) {
			for {
				//lock.Lock()
				rwLock.RLock()
				time.Sleep(time.Millisecond * 3)
				rwLock.RUnlock()
				//lock.Unlock()
				atomic.AddInt32(&count, 1) //計數讀了多少次
			}
		}(a)
	time.Sleep(time.Second * 3)
	fmt.Println(atomic.LoadInt32(&count))
}

func main() {
	//	testMap()
	testRWLock()
}