因為公司安排,我臨時從Java項目組調往Go項目組,經過差不多5天業餘時間對Go學習後,架構師讓我給公司同事進行了Golang的分享和培訓.
同事們很熱愛技術, 本來預計40分鐘的分享, 由於同事們積極的討論和Go大佬同事的熱情補充分享, 最終持續了2個多小時. 我把此次分享中幾個討論熱烈的重要知識點記錄下來, 方便大家入門GO的時候避坑.
go中的dealock主要分為兩類:
1. channel相關的死結
讀寫nil channel,導致的死結
func main() { ch := make(chan int) ch <- 1 }
goroutine 1 [chan send]:
image.png
2. 教科書式的死結
這個是作業系統教科書中的死結,互相等待對方釋放鎖。
var lock1 *sync.Mutexvar lock2 *sync.Mutexfunc main() { lock1 = new(sync.Mutex) lock2 = new(sync.Mutex) go func() { lock1.Lock() fmt.Println("I'm a goroutine,I have lock1,and I need lock2.") time.Sleep(time.Second) lock2.Lock() lock2.Unlock() lock1.Unlock() }() lock2.Lock() fmt.Println("I'm the main goroutine,I have lock2,and I need lock1.") time.Sleep(time.Second) lock1.Lock() lock1.Unlock() lock2.Unlock() time.Sleep(5 * time.Second)}
goroutine 1 [semacquire]:
image.png
易錯點
Q: 是不是只要唯一的mian goroutine阻塞了,就會導致死結
A: 不是,只有nil channel導致的阻塞,才會導致死結. 由於其他原因導致的阻塞不會導致死結,如下面這個例子.
func main() { log.Fatal(http.ListenAndServe(":8000", nil)) //block log.Print("This doesn't print") fmt.Println("Can't reach here.")}
Q: 什麼時候go的runtime會檢索到deadlock
A: 只有當所有
的goroutine都不能被訪問時候, go的runtime會檢測到這種情況,並拋出deadlock. (TODO,這個結論還是不太完善)
更多deadlock的例子: https://gitee.com/sicnu-yudidi/go/tree/master/go-3/deadlock
https://programming.guide/go/detect-deadlock.html
https://stackoverflow.com/questions/42432880/why-does-this-goroutine-block