在Go語言中,select語句就像switch語句,但是在select語句中,case語句引用通信,即通道上的發(fā)送或接收操作。
語法:
select{
case SendOrReceive1: // 語句
case SendOrReceive2: // 語句
case SendOrReceive3: // 語句
.......
default: // Statement
}在本文中,我們將學(xué)習(xí)如何使用默認情況來避免死鎖。但是首先,我們了解什么是deadlock?
死鎖:當(dāng)您試圖從通道讀取或?qū)懭霐?shù)據(jù)但通道沒有值時。因此,它阻塞goroutine的當(dāng)前執(zhí)行,并將控制傳遞給其他goroutine,但是如果沒有其他goroutine可用或其他goroutine睡眠,由于這種情況,程序?qū)⒈罎?。這種現(xiàn)象稱為死鎖。如下面的實例所示:
package main
func main() {
//創(chuàng)建通道
//出現(xiàn)死鎖是因為沒有g(shù)oroutine在寫
//因此,select語句被永遠阻塞
c := make(chan int)
select {
case <-c:
}
}輸出:
fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan receive]: main.main()
為了避免這種情況,我們在select語句中使用默認case。換句話說,當(dāng)程序中出現(xiàn)死鎖時,將執(zhí)行select語句的默認情況以避免死鎖。如下例所示,我們在select語句中使用默認情況以避免死鎖。
package main
import "fmt"
func main() {
//創(chuàng)建通道
c := make(chan int)
select {
case <-c:
default:
fmt.Println("!.. Default case..!")
}
}輸出:
!.. Default case..!
當(dāng)select語句只有nil通道時,也允許使用默認情況。如下面的實例所示,通道c是nil,所以默認情況下執(zhí)行,如果這里的默認情況是不可用的,那么程序?qū)⒂肋h被阻塞,死鎖出現(xiàn)。
package main
import "fmt"
func main() {
//創(chuàng)建通道
var c chan int
select {
case x1 := <-c:
fmt.Println("Value: ", x1)
default:
fmt.Println("Default case..!")
}
}輸出:
Default case..!