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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

golang中的互斥锁

發(fā)布時間:2025/6/15 编程问答 12 豆豆
生活随笔 收集整理的這篇文章主要介紹了 golang中的互斥锁 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

簡介

每個資源都對應一個可稱為"互斥鎖"的標記,這個標記用來保證在任意時刻,只有一個協(xié)程(線程)訪問該資源.其他的協(xié)程只能等待

由標準庫sync中的Mutex結構體類型表示.
sync.Mutex類型只有兩個公開的指針方法,Lock和Unlock.
Lock鎖定當前的共享資源,Unlock進行解鎖

使用互斥鎖時,一定要注意:對資源操作完成后,一定要解鎖,否則出現(xiàn)流程執(zhí)行異常,死鎖問題.通常借助defer.鎖定后,立即使用defer語句保證互斥鎖及時解鎖

var mutex sync.Mutex //定義互斥鎖變量func write() {muter.Lock()defer muter.Unlock() }

使用

//新創(chuàng)建為0.表示沒有加鎖,鎖只有1把 var mutex sync.Mutexfunc printer(str string) {mutex.Lock()for _, ch := range str {fmt.Println(string(ch))time.Sleep(300 * time.Millisecond)}//共享數(shù)據(jù)訪問結束mutex.Unlock() }func person1() {printer("11") }func person2() {printer("222") }func main() {//先,因為他先獲得鎖go person1()//后go person2()for {;} }

不是強制性的

互斥鎖的使用是主動控制互斥鎖,即一個愿打一個愿挨。比如即使一個routine里用了Lock(),但在另一個routine可以不理會這個鎖就能訪問這個struct,只需要不調(diào)用Lock()就行。例子如下

package mainimport ("fmt""sync""time" )type SafeCounter struct {v map[string]intmux sync.Mutex }func (c *SafeCounter) Inc(key string) {c.mux.Lock()time.Sleep(3 * time.Second)c.v[key]++c.mux.Unlock() }func main() {c := SafeCounter{v: make(map[string]int)}go c.Inc("somekey")time.Sleep(1 * time.Second)c.v["somekey"]++fmt.Println(c.v["somekey"])time.Sleep(3 * time.Second)fmt.Println(c.v["somekey"]) }

輸出

1 2

c.v["somekey"]++之前,是已經(jīng)鎖了,本應該等2-3秒,才能輸出,但是從程序開始運行,只過了1秒就輸出了,說明Lock只是一種人為的互斥,是一種協(xié)議,并不是強制。

已經(jīng)鎖定的Mutex與特定的goroutine無關聯(lián)

已經(jīng)鎖定的Mutex并不與特定的goroutine相關聯(lián),這樣可以利用一個goroutine對其加鎖,再利用其他goroutine對其解鎖,例子如下

package mainimport ("fmt""sync""time" )type MyStruct struct {v intmux sync.Mutex }func (s *MyStruct) Lock() {s.mux.Lock() }func (s *MyStruct) Unlock() {s.mux.Unlock() }func main() {s := MyStruct{v: 0}s.v = 1fmt.Printf("%+v\n", s)go s.Lock()time.Sleep(1 * time.Second)fmt.Printf("%+v\n", s)go s.Unlock()time.Sleep(1 * time.Second)fmt.Printf("%+v\n", s) }

輸出

{v:1 mux:{state:0 sema:0}} {v:1 mux:{state:1 sema:0}} {v:1 mux:{state:0 sema:0}}

可以看出,可以一個routine里鎖定,另一個routine里解鎖。因為鎖只和具體變量關聯(lián),和routine無關,只要這個變量是共享的,比如通過指針傳遞,或者全局變量都可以。

雖然互斥鎖可以被直接的在多個Goroutine之間共享,但是我們還是強烈建議把對同一個互斥鎖的成對的鎖定和解鎖操作放在同一個層次的代碼塊中。例如,在同一個函數(shù)或方法中對某個互斥鎖的進行鎖定和解鎖。

總結

以上是生活随笔為你收集整理的golang中的互斥锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。