square-gopher.png
在 go 語言中提供了并發(fā)編程模型和工具外近哟,還提供傳統(tǒng)的同步工具鎖稿黄,包括互斥鎖和讀寫鎖
有關(guān)互斥鎖有些內(nèi)容我們必須清楚挺峡,也就是對于同一個互斥鎖的鎖定操作和解鎖操作應(yīng)該是成對出現(xiàn)枢贿。
如果一個鎖定一個已經(jīng)鎖定的互斥鎖贱案,那么進行重復(fù)鎖定操作的 goroutine 將被阻塞魏身,直到該互斥鎖回到解鎖狀態(tài)惊橱。
package main
import(
"fmt"
"sync"
"time"
)
func main(){
var mutex sync.Mutex
fmt.Println("Lock the lock. main groutine")
mutex.Lock()
fmt.Println("The lock is locked main groutine")
for i:= 1; i <= 3; i++{
go func(i int){
fmt.Printf("Lock the lock. (g%d)\n",i)
mutex.Lock()
fmt.Printf("The lock is locked. (g%d)\n",i)
}(i)
}
time.Sleep(time.Second)
fmt.Println("Unlock the lock. main goroutine")
mutex.Unlock()
fmt.Println("The lock is unlocked. main groutine")
time.Sleep(time.Second)
}
- 首先在 main 的 goroutine 對 mutex 進行鎖定
- 然后循環(huán)創(chuàng)建三個 goroutine 并依次對這個已經(jīng)鎖定的 mutex 進行鎖定
- 最后 main goroutine 中對 mutex 進行解鎖,并使用 time.Sleep 讓 main goroutine 在運行一段時間以便觀察
Lock the lock. main groutine
The lock is locked main groutine
Lock the lock. (g3)
Lock the lock. (g1)
Lock the lock. (g2)
Unlock the lock. main goroutine
The lock is locked. main groutine
The lock is locked. (g3)
重復(fù)解鎖已經(jīng)鎖定的鎖也會引發(fā)運行時的錯誤箭昵。
import(
"fmt"
"sync"
)
func main() {
defer func(){
fmt.Println("try to recover the panic.")
if p := recover(); p != nil{
fmt.Printf("Recovered the panic(%#v).\n",p)
}
}()
var mutex sync.Mutex
fmt.Println("Lock the lock.")
mutex.Lock()
fmt.Println("the lock is locked")
fmt.Println("Unlock the lock")
mutex.Unlock()
fmt.Println("the lock is unlocked gain.")
fmt.Println("Unlock the lock again")
mutex.Unlock()
}
fatal error: sync: unlock of unlocked mutex
th-9.jpeg
如果想深入了解 go 語言并發(fā)編程可以閱讀《go 語言并發(fā)編程實戰(zhàn)》這本書税朴,內(nèi)容比較深。
參考 go 語言并發(fā)編程實戰(zhàn)