什么是死鎖,在Go的協(xié)程里面死鎖通常就是永久阻塞了,你拿著我的東西,要我先給你然后再給我,我拿著你的東西又讓你先給我,不然就不給你。我倆都這么想,這事就解決不了了。
先上代碼:
func main() { ch := make(chan int, 0) ch - 666 x := - ch fmt.Println(x) }
我們可以看到這是一個沒有緩存能力的管道,然后往里面寫666,然后就去管道里面讀。這樣肯定會出現(xiàn)問題?。∫粋€無緩存能力的管道,沒有人讀,你也寫不了,沒有人寫,你也讀不了,這正是一種死鎖!
fatal error: all goroutines are asleep - deadlock!
解決辦法很簡單,開辟兩條協(xié)程,一條協(xié)程寫,一條協(xié)程讀。
func main() { ch := make(chan int,0) ch - 666 go func() { - ch }() }
我們可以看到,這條協(xié)程開辟在將數(shù)字寫入到管道之后,因為沒有人讀,管道就不能寫,然后寫入管道的操作就一直阻塞。這時候你就有疑惑了,不是開辟了一條協(xié)程在讀嗎?但是那條協(xié)程開辟在寫入管道之后,如果不能寫入管道,就開辟不了協(xié)程。
如果相互要求對方先讀/寫,自己再讀/寫,就會造成死鎖。
func main() { chHusband := make(chan int,0) chWife := make(chan int,0) go func() { select { case - chHusband: chWife-888 } }() select { case - chWife: chHusband - 888 } }
先來看看老婆協(xié)程,chWife只要能讀出來,也就是老婆有錢,就給老公發(fā)個八百八十八的大紅包。
再看看老公的協(xié)程,一看不得了,咋啦?老公也說只要他有錢就給老婆包個八百八十八的大紅包。
兩個人都說自己沒錢,老公也給老婆發(fā)不了紅包,老婆也給老公發(fā)不了紅包,這就是死鎖!
先來看一看代碼:
func main() { var rmw09 sync.RWMutex ch := make(chan int,0) go func() { rmw09.Lock() ch - 123 rmw09.Unlock() }() go func() { rmw09.RLock() x := - ch fmt.Println("讀到",x) rmw09.RUnlock() }() for { runtime.GC() } }
這兩條協(xié)程,如果第一條協(xié)程先搶到了只寫鎖,另一條協(xié)程就不能搶只讀鎖了,那么因為另外一條協(xié)程沒有讀,所以第一條協(xié)程就寫不進。
如果第二條協(xié)程先搶到了只讀鎖,另一條協(xié)程就不能搶只寫鎖了,那么因為另外一條協(xié)程沒有寫,所以第二條協(xié)程就讀不到。
到此這篇關(guān)于詳解Golang并發(fā)操作中常見的死鎖情形的文章就介紹到這了,更多相關(guān)Golang 并發(fā)死鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
標簽:黑龍江 新余 嘉峪關(guān) 延邊 江西 張掖 宜賓 武漢
巨人網(wǎng)絡通訊聲明:本文標題《詳解Golang并發(fā)操作中常見的死鎖情形》,本文關(guān)鍵詞 詳解,Golang,并發(fā),操作,中,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡,涉及言論、版權(quán)與本站無關(guān)。