golang中的读写锁
生活随笔
收集整理的這篇文章主要介紹了
golang中的读写锁
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
簡介
互斥鎖本質是當一個協程訪問的時候,其他協程都不能訪問.
其實主要是想:修改數據要同步,這樣其他協程才可以感知到,所以真正的互斥應該是讀取和修改,修改和修改之間,讀和讀是沒有互斥操作的必要的
讀寫鎖可以讓多個讀并發,但是對于寫是互斥的.
當一個協程在寫的時候,其他協程不能讀也不能寫
同時只能存在寫鎖定或讀鎖定(讀和寫互斥)
go中的讀寫鎖由結構類型sync.RWMutex表示.這個類型的方法集合中包含兩對方法
一組是對寫操作的鎖定和解鎖,簡稱:寫鎖定和寫解鎖
另一組表示對讀操作的鎖定和解鎖,簡稱為讀鎖定和讀解鎖
func (*RWMutex) RLock() func (*RWMutex) RUlock()讀時共享,寫時獨占.
寫優先級比讀高
讀鎖也算個鎖,鎖只能有一把
package mainimport ("fmt""sync" )func main() {var mutex sync.Mutexfmt.Printf("%+v\n", mutex)mutex.Lock()fmt.Printf("%+v\n", mutex)mutex.Unlock()fmt.Printf("%+v\n", mutex) }輸出
{state:0 sema:0} {state:1 sema:0} {state:0 sema:0}可以看出當Lock()時,state為1,Unlock()時,state為0。
使用
讀寫鎖,最好不要和channel一起使用會造成死鎖
//創建讀寫鎖 var mx sync.RWMutex//讀 func readGo(in <-chan int, idx int) {for {//mx.RLock() //讀鎖//要求寫端同時在線,自己阻塞num := <-infmt.Println("讀取: ", num, idx)time.Sleep(time.Millisecond * 300) //放大實驗現象//mx.RUnlock()}}//寫 func writeGo(out chan<- int, idx int) {for {//生成隨機數num := rand.Intn(1000)mx.Lock() //寫鎖out <- numfmt.Println("------寫入: ", num, idx)time.Sleep(time.Millisecond * 30) //放大實驗現象mx.Unlock()} }func main() {//播種隨機數rand.Seed(time.Now().UnixNano())ch := make(chan int) //數據傳遞的channelfor i := 0; i < 5; i++ {go writeGo(ch, i+1)}for i := 0; i < 5; i++ {go readGo(ch, i+1)}for {;}}全局變量數據同步
//創建讀寫鎖 var mx sync.RWMutex var i int //全局變量模擬共享數據//讀 func readGo(idx int) {for {mx.RLock() //讀鎖num := ifmt.Println("讀取: ", num, idx)//time.Sleep(time.Millisecond * 30) //放大實驗現象mx.RUnlock()}}//寫 func writeGo(idx int) {for {mx.Lock() //寫鎖//生成隨機數num := rand.Intn(1000)i = numfmt.Println("------寫入: ", num, idx)time.Sleep(time.Millisecond * 30) //放大實驗現象mx.Unlock()} }func main() {//播種隨機數rand.Seed(time.Now().UnixNano())for i := 0; i < 5; i++ { //5個讀過程go readGo(i+1)}for i := 0; i < 5; i++ { //5個寫過程go writeGo(i+1)}for {;} }總結
以上是生活随笔為你收集整理的golang中的读写锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: golang中的互斥锁
- 下一篇: golang中的条件变量