鎖和 sync 包 go學習

2021-10-03 04:28:57 字數 1027 閱讀 4627

在一些複雜的程式中,通常通過不同執行緒執行不同應用來實現程式的併發。當不同執行緒要使用同乙個變數時,經常會出現乙個問題:無法預知變數被不同執行緒修改的順序!(這通常被稱為資源競爭,指不同執行緒對同一變數使用的競爭)顯然這無法讓人容忍,那我們該如何解決這個問題呢?

經典的做法是一次只能讓乙個執行緒對共享變數進行操作。當變數被乙個執行緒改變時(臨界區),我們為它上鎖,直到這個執行緒執行完成並解鎖後,其他執行緒才能訪問它。

特別是我們之前章節學習的 map 型別是不存在鎖的機制來實現這種效果(出於對效能的考慮),所以 map 型別是非執行緒安全的。當並行訪問乙個共享的 map 型別的資料,map 資料將會出錯。

在 go 語言中這種鎖的機制是通過 sync 包中 mutex 來實現的。sync **於 "synchronized" 一詞,這意味著執行緒將有序的對同一變數進行訪問

sync.mutex是乙個互斥鎖,它的作用是守護在臨界區入口來確保同一時間只能有乙個執行緒進入臨界區。

假設 info 是乙個需要上鎖的放在共享記憶體中的變數。通過包含mutex來實現的乙個典型例子如下:

import  "sync"

type info struct

如果乙個函式想要改變這個變數可以這樣寫:

func update(info *info)
還有乙個很有用的例子是通過 mutex 來實現乙個可以上鎖的共享緩衝器:

type syncedbuffer struct
在 sync 包中還有乙個rwmutex鎖:他能通過rlock()來允許同一時間多個執行緒對變數進行讀操作,但是只能乙個執行緒進行寫操作。如果使用lock()將和普通的mutex作用相同。包中還有乙個方便的once型別變數的方法once.do(call),這個方法確保被呼叫函式只能被呼叫一次。

學習golang之同步原語sync包

資源競爭 以上被加鎖保護的 sum i 片段又稱為臨界區。這個示例開啟了 10 個協程,它們同時讀取 sum 的值。因為 readsum 函式並沒有任何加鎖控制,所以它不是併發安全的,即乙個 goroutine 正在執行 sum i 操作的時候,另乙個 goroutine 可能正在執行 b sum ...

Go學習 11 包和封裝

這裡的公有和私有是針對包來說的 記住 乙個資料夾就是乙個包 乙個包裡的所有檔案的開頭都是一樣的package 包名 包名一般就是檔名,main函式所在的包除外,當然也可以不一樣 大寫字母開頭的元素可以匯出到其它包中使用。乙個包裡的檔案之間相互引用匯出的屬性 變數 函式等,是不需要import的 引用...

28 學習 Go 協程 互斥鎖和讀寫鎖

在 19.學習 go 協程 詳解通道 通道 這一節裡我詳細地介紹信道的一些用法,要知道的是在 go 語言中,通道的地位非常高,它是 first class 級別的,面對併發問題,我們始終應該優先考慮使用通道,如果通過通道解決不了的,不得不使用共享記憶體來實現併發程式設計的,那 golang 中的鎖機...