<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
前言:
單個執行緒時資料操作的只有一個執行緒,資料的修改也只有一個執行緒參與,資料相對來說是安全的,多執行緒時對資料操作的不止一個執行緒,所以同時對資料進行修改的時候難免紊亂
互斥鎖是為了並行的安全,在多個goroutine
共同工作的時候,對於共用的資料十分不安全寫入時容易因為競爭造成資料不必要的丟失。互斥鎖一般加在共用資料修改的地方。
package main import ( "fmt" "sync" ) var x int = 0 var wg sync.WaitGroup func add() { defer wg.Done() for i := 0; i < 5000; i++ { x++ } } func main() { wg.Add(2) go add() go add() wg.Wait() fmt.Println(x) } /* 列印結果:(每次列印不一樣,正常的結果應該是10000) 6051 5059 5748 10000 */
package main import ( "fmt" "sync" ) var x int = 0 var wg sync.WaitGroup // 建立一個鎖物件 var lock sync.Mutex func add() { defer wg.Done() for i := 0; i < 5000; i++ { //加鎖 lock.Lock() x++ //解鎖 lock.Unlock() } } func main() { wg.Add(2) //開啟兩個執行緒 go add() go add() wg.Wait() fmt.Println(x) } /* 列印結果: 全為10000 */
使用鎖的時候,安全與效率往往需要互相轉換,對資料進行操作的時候,只會進行資料的讀與寫。 而讀與讀之間可以同時進行,讀與寫之間需要保證寫的時候不去讀。此時為了提高效率就發明讀寫鎖,在讀寫鎖機制下,安全沒有絲毫降低,但效率進行了成倍的提升提升的效率在讀與寫操作次數差異越大時越明顯
程式碼如下(範例):
package main import ( "fmt" "sync" "time" ) var ( x = 0 rwlock sync.RWMutex wg sync.WaitGroup ) func write() { defer wg.Done() rwlock.Lock() x++ rwlock.Unlock() } func read() { wg.Done() //開啟讀鎖 rwlock.RLock() fmt.Println(x) //釋放讀鎖 rwlock.RUnlock() } func main() { start := time.Now() for i := 0; i < 100; i++ { wg.Add(1) go write() } // time.Sleep(time.Second) for i := 0; i < 10000; i++ { wg.Add(1) go read() } wg.Wait() fmt.Println(time.Now().Sub(start)) }
在多個goroutine
中往往會由於執行緒不同步造成資料讀寫的衝突,特別是在進行檔案開啟物件建立的時候,可能會造成向關閉的檔案寫內容,使用未初始化的物件,或者對一個物件進行多次初始化。
sync.once
保證函數內的程式碼只執行一次, 實現的機制是在once內部有一個標誌位,在執行程式碼的時候執行一次之後標誌位將置為1後續判斷標誌位,如果標誌位被改為1則無法再進行操縱
sync.Once.Do()
傳進去的函數引數無參無返,一個once物件只能執行一次Do方法,向Do方法內傳多個不同的函數時只能執行第一個傳進去的,傳進去Do方法的函數無參無返,可以用函數閉包把需要的變數傳進去
func f2(a <-chan int, b chan<- int) { for { x, ok := <-a if !ok { break } fmt.Println(x) b <- x * 10 } // 確保b通道只關閉一次 once.Do(func() { close(b) }) }
原子包將指定的資料進行安全的加減交換操作; 網上還有一大堆關於原子包的api感興趣的小夥伴可以自行百度,這裡就不細細闡述了
package main import ( "fmt" "sync" "sync/atomic" ) var x int64 = 0 var wg sync.WaitGroup /* 原子操作是將資料進行打包枷鎖,直接通過指定的函數進行相應的操作 可以使用load讀取、store寫入、add修改、swap交換。 // 類似於讀取一個變數、對一個變數進行賦值 */ func addone() { // 沒有加鎖進行並行的話,會產生資料丟失的情況 defer wg.Done() // x++ // 不用加鎖也可以使用的行雲流水 // 第一個引數是進行操作的資料,第二個是增加的步長 atomic.AddInt64(&x, 1) } func csf() { // 進行比較相等則將新值替換舊值 ok := atomic.CompareAndSwapInt64(&x, 100, 200) fmt.Println(ok, x) } func main() { for i := 0; i < 50000; i++ { wg.Add(1) go addone() } wg.Wait() fmt.Println(x) x = 100 csf() fmt.Println(123) }
總結:
讀寫鎖區分讀者和寫者,而互斥鎖不區分 互斥鎖同一時間只允許一個執行緒存取該物件,無論讀寫;讀寫鎖同一時間內只允許一個寫者, 但是允許多個讀者同時讀物件。 聯絡:讀寫鎖在獲取寫鎖的時候機制類似於互斥鎖。
到此這篇關於Go語言執行緒安全之互斥鎖與讀寫鎖的文章就介紹到這了,更多相關Go語言互斥鎖與讀寫鎖內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45