Go讀寫鎖操作方法示例詳解

 更新時間:2022年07月05日 17:29:09   作者:LiberHome  
這篇文章主要為大家介紹了Go讀寫鎖方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

前面講到,在資源競爭的時候可以使用互斥鎖,保證了資源訪問的唯一性,但也降低了性能,仔細分析一下場景,如果只是讀取數據,無論多少個goroutine都是不會存在邏輯上的互斥操作的。

這里讀寫鎖?? RWMutex就應運而生了,RWMutex可以分別針對讀操作和寫操作進行上鎖和解鎖。

RWMutex同一時刻允許多個讀操作進行,但只允許一個寫操作進行,同時,在某一個寫操作進行的時候,讀操作不可進行。

讀寫鎖有很多方法

  • 方法一: RLock 這個方法是讀鎖,當寫鎖存在的時候,無法加載讀鎖,只有當不存在鎖,或者只有讀鎖的時候才能使用。讀鎖可以同時加載多個,適用于多度寫少的場景。
  • 方法二: RUnlock 這個方法是讀解鎖,用來撤銷單次的讀鎖操作。
  • 方法三: Lock 這個方法是寫上鎖,如果在添加寫上鎖之前已經有其他的讀鎖和寫鎖了,此時,這個Lock會被阻塞,直到可以使用。
  • 方法四: Unlock 這個方法是寫解鎖,如果沒有綁定寫鎖就直接寫解鎖,會引發運行時錯誤。

讀操作

下面用實際的代碼做例子,看一下讀操作:

package main
import (
    "fmt"
    "sync"
    "time"
)
//新建一個鎖對象的指針,然后待會兒再指針中創建這個鎖的對象
var rwMutex *sync.RWMutex
//為了保證 子的goroutine先執行,可以使用同步等待組wg,這里創建wg的指針類型
var wg *sync.WaitGroup
func main() {
    rwMutex = new(sync.RWMutex)
    wg = new(sync.WaitGroup)
    wg.Add(2)//這里記得+add
    //    在主函數中 啟動2條goroutine
    go readData(1)
    go readData(2)
    wg.Wait()
    fmt.Println("main func end")
}
func readData(i int) {
    defer wg.Done()
    fmt.Println(i, "start locking!")
    //    給讀操作 上鎖
    rwMutex.RLock()
    //    讀數據
    fmt.Println(i, "Reading data")
    //  睡一下
    time.Sleep(1 * time.Second)
    //    讀解鎖
    rwMutex.RUnlock()
    //打印提示信息
    fmt.Println(i, "Read over")
}

代碼運行結果如下:

2 start locking!
2 Reading data
1 start locking!
1 Reading data
2 Read over
1 Read over
main func end

從打印結果可知,第二條goroutine先上讀鎖,然后第二條開始讀取,然后第一條上讀鎖【從這里就可以看出,因為第二條的讀鎖還沒讀解鎖,第一條的讀鎖就上了,所以這里的讀鎖并不互斥】,之后第一條開始讀取,第二條讀解鎖,第一條讀解鎖。主goroutine結束。

寫操作

package main
import (
    "fmt"
    "sync"
    "time"
)
//新建一個鎖對象的指針,然后待會兒再指針中創建這個鎖的對象
var rwMutex *sync.RWMutex
//為了保證 子的goroutine先執行,可以使用同步等待組wg,這里創建wg的指針類型
var wg *sync.WaitGroup
func main() {
    rwMutex = new(sync.RWMutex)
    wg = new(sync.WaitGroup)
    wg.Add(4)
    //    在主函數中 啟動2條goroutine
    go readData(1)
    go readData(2)
    go writeData(3)
    go writeData(4)
    wg.Wait()
    fmt.Println("main func end")
}
func readData(i int) {
    defer wg.Done()
    fmt.Println(i, "start locking!")
    //    給讀操作 上鎖
    rwMutex.RLock()
    //    讀數據
    fmt.Println(i, "Reading data")
    //  睡一下
    time.Sleep(1 * time.Second)
    //    讀解鎖
    rwMutex.RUnlock()
    //打印提示信息
    fmt.Println(i, "Read over")
}
func writeData(i int) {
    defer wg.Done()
    fmt.Println(i, " Writing Start")
    //寫上鎖
    rwMutex.Lock()
    fmt.Println(i, "~~~ writing right now~~~")
    time.Sleep(1 * time.Second)
    rwMutex.Unlock()
    fmt.Println(i, "writing completed")
}

代碼運行結果如下:

2 start locking!
2 Reading data
4  Writing Start
1 start locking!
3  Writing Start
2 Read over
4 ~~~ writing right now~~~
4 writing completed
1 Reading data
1 Read over
3 ~~~ writing right now~~~
3 writing completed
main func end

分析可知,只有在goroutine4結束寫之后goroutine3才拿到權限開始寫。

不過講真,到處都是lock 和 unlock,臨界區什么的,真的是臃腫又容易出問題。
go語言中多個協程想共享數據的時候,將會有更加優雅的處理方式。

以上就是Go讀寫鎖方法示例詳解的詳細內容,更多關于Go讀寫鎖方法的資料請關注腳本之家其它相關文章!

相關文章

  • golang json性能分析詳解

    golang json性能分析詳解

    json格式可以算我們日常最常用的序列化格式之一了,Go語言作為一個由Google開發,號稱互聯網的C語言的語言,自然也對JSON格式支持很好。下面這篇文章主要給大家詳細分析介紹了golang json性能的相關資料,需要的朋友可以參考下。
    2018-02-02
  • 淺談golang 中time.After釋放的問題

    淺談golang 中time.After釋放的問題

    這篇文章主要介紹了淺談golang 中time.After釋放的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • golang語言中wasm 環境搭建的過程詳解

    golang語言中wasm 環境搭建的過程詳解

    將 golang 打包為 WASM,通常有兩種打包方式,一種是 golang 自帶的,另外是使用 tinygo ,接下來通過本文給大家介紹golang語言中wasm 環境搭建的過程,感興趣的朋友一起看看吧
    2021-11-11
  • Go 中 slice 的 In 功能實現探索

    Go 中 slice 的 In 功能實現探索

    這篇文章主要介紹了Go 中 slice 的 In 功能實現探索,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-09-09
  • GO語言常用的文件讀取方式

    GO語言常用的文件讀取方式

    這篇文章主要介紹了GO語言常用的文件讀取方式,涉及一次性讀取、分塊讀取與逐行讀取等方法,是非常實用的技巧,需要的朋友可以參考下
    2014-12-12
  • Golang項目搭配nginx部署反向代理負載均衡講解

    Golang項目搭配nginx部署反向代理負載均衡講解

    這篇文章主要為大家介紹了Golang項目搭配nginx部署正反向代理負載均衡講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • 詳解go語言單鏈表及其常用方法的實現

    詳解go語言單鏈表及其常用方法的實現

    這篇文章主要介紹了詳解go語言單鏈表及其常用方法的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • 在goland中配置gofmt的操作

    在goland中配置gofmt的操作

    這篇文章主要介紹了在goland中配置gofmt的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • golang log4go的日志輸出優化詳解

    golang log4go的日志輸出優化詳解

    log4go源于google的一項log工程,但官方已經停止維護更新,下面這篇文章主要給大家介紹了關于golang log4go的日志輸出優化的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-12-12
  • 使用client-go工具調用kubernetes API接口的教程詳解(v1.17版本)

    使用client-go工具調用kubernetes API接口的教程詳解(v1.17版本)

    這篇文章主要介紹了使用client-go工具調kubernetes API接口(v1.17版本),本文通過圖文實例相結合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08

最新評論

美丽人妻被按摩中出中文字幕