日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Golang——死锁、互斥锁、读写锁的实现

發布時間:2025/3/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Golang——死锁、互斥锁、读写锁的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

死鎖:

  • 什么是鎖呢?就是某個協程(線程)在訪問某個資源時先鎖住,防止其它協程的訪問,等訪問完畢解鎖后其他協程再來加鎖進行訪問。這和我們生活中加鎖使用公共資源相似,例如:公共衛生間。
  • 死鎖是指兩個或兩個以上的進程在執行過程中,由于競爭資源或者由于彼此通信而造成的一種阻塞的現象,若無外力作用,它們都將無法推進下去。此時稱系統處于死鎖狀態或系統產生了死鎖,
func main() {ch := make(chan int)ch <- 1 // 先讀數據,但是這個時候還沒有開始寫,會一直卡在這里,下面的都執行不了,下面的寫的操作也永遠不會唄執行,解決方案就是把它放在寫的下面fmt.Println("send")go func() {<-ch // I will never be called for the main routine is blocked!fmt.Println("received")}()fmt.Println("over") }

互斥鎖:

每個資源都對應于一個可稱為 互斥鎖的標記,這個標記用來保證在任意時刻,只能有一個協程(線程)訪問該資源。其它的協程只能等待?;コ怄i是傳統并發編程對共享資源進行訪問控制的主要手段,它由標準庫sync中的Mutex結構體類型表示。sync.Mutex類型只有兩個公開的指針方法,Lock和Unlock。Lock鎖定當前的共享資源,Unlock進行解鎖。
在使用互斥鎖時,一定要注意:對資源操作完成后,一定要解鎖,否則會出現流程執行異常,死鎖等問題,通常借助defer。鎖定后,立即使用defer語句保證互斥鎖及時解鎖。

演示:

由于添加了互斥鎖,可以按序先輸出hello再輸出 world。但這里需要我們自行創建互斥鎖,并在適當的位置對鎖進行釋放。

var mutex sync.Mutex // 定義互斥鎖變量 mutexfunc printer(str string) {mutex.Lock() // 添加互斥鎖defer mutex.Unlock() // 使用結束時解鎖for _, data := range str { // 迭代器fmt.Printf("%c", data)time.Sleep(time.Second) // 放大協程競爭效果}fmt.Println() }func person1(s1 string) {printer(s1) }func person2() {printer("world") // 調函數時傳參 }func main() {go person1("hello") // main 中傳參go person2()for {} }

讀寫鎖:

互斥鎖的本質是當一個goroutine訪問的時候,其他goroutine都不能訪問。這樣在資源同步,避免競爭的同時也降低了程序的并發性能。程序由原來的并行執行變成了串行執行。其實,當我們對一個不會變化的數據只做“讀”操作的話,是不存在資源競爭的問題的。因為數據是不變的,不管怎么讀取,多少goroutine同時讀取,都是可以的。所以問題不是出在“讀”上,主要是修改,也就是“寫”。修改的數據要同步,這樣其他goroutine才可以感知到。所以真正的互斥應該是讀取和修改、修改和修改之間,讀和讀是沒有互斥操作的必要的。因此,衍生出另外一種鎖,叫做讀寫鎖。讀寫鎖可以讓多個讀操作并發,同時讀取,但是對于寫操作是完全互斥的。也就是說,當一個goroutine進行寫操作的時候,其他goroutine既不能進行讀操作,也不能進行寫操作。

  • 讀寫鎖控制下的多個寫操作之間都是互斥的,并且寫操作與讀操作之間也都是互斥的。但是,多個讀操作之間不存在互斥關系。

GO中的讀寫鎖由結構體類型sync.RWMutex表示。此類型的方法集合中包含兩對方法:
一組是對寫操作的鎖定和解鎖,簡稱“寫鎖定”和“寫解鎖”:

func (*RWMutex)Lock() func (*RWMutex)Unlock()

另一組表示對讀操作的鎖定和解鎖,簡稱為“讀鎖定”與“讀解鎖”:

func (*RWMutex)RLock() func (*RWMutex)RUlock()

演示:

var count int // 全局變量count var rwlock sync.RWMutex // 全局讀寫鎖 rwlockfunc read(n int) {rwlock.RLock()fmt.Printf("讀 goroutine %d 正在讀取數據...\n", n)num := countfmt.Printf("讀 goroutine %d 讀取數據結束,讀到 %d\n", n, num)defer rwlock.RUnlock() } func write(n int) {rwlock.Lock()fmt.Printf("寫 goroutine %d 正在寫數據...\n", n)num := rand.Intn(1000)count = numfmt.Printf("寫 goroutine %d 寫數據結束,寫入新值 %d\n", n, num)defer rwlock.Unlock() }func main() {for i := 0; i < 5; i++ {go read(i + 1)}for i := 0; i < 5; i++ {go write(i + 1)}for {} }

總結

以上是生活随笔為你收集整理的Golang——死锁、互斥锁、读写锁的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。