English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Go言語では、select文はswitch文、しかしselect文では、case文は通信を参照します、つまりチャネル上の送信または受信操作です。
文法:
select{ case SendOrReceive1: // 文 case SendOrReceive2: // 文 case SendOrReceive3: // 文 ....... default: // 文 }
この記事では、デフォルトケースを使用して死锁を避ける方法について学びますが、まず最初に、何がdeadlockかを理解する必要があります。
死锁:チャネルから読み取ろうとして、またはチャネルに値を書き込もうとして、チャネルに値がない場合。したがって、それはgoroutineの現在の実行をブロックし、制御を他のgoroutineに渡しますが、他のgoroutineが利用できない場合や他のgoroutineが眠っている場合、このような状況によって、プログラムがクラッシュします。この現象を死锁と呼びます。以下の例を参照してください:
package main func main() { //チャネルを作成 //死锁が発生するのは、goroutineが書き込んでいないためです //したがって、select文は永远にブロックされます c := make(chan int) select { case <-c: } }
出力:
致命的なエラー: すべてのgoroutineが寝ている - deadlock! goroutine 1 [chan receive]: main.main()
このような状況を避けるために、select文でデフォルトケースを使用します。言い換えれば、プログラムに死锁が発生した場合、select文のデフォルトケースを実行して死锁を避けることができます。以下の例では、select文でデフォルトケースを使用して死锁を避ける例を示します。
package main import "fmt" func main() { //チャネルを作成 c := make(chan int) select { case <-c: default: fmt.Println("!.. デフォルトケース..!") } }
出力:
!.. デフォルトケース..!
select文がnilチャネルのみを持っている場合でも、デフォルトケースを使用することが許可されています。以下の例では、チャネルcがnilであり、したがってデフォルトケースで実行されます。ここでのデフォルトケースが利用できない場合、プログラムは永远にブロックされ、死锁が発生します。
package main import "fmt" func main() { //チャネルを作成 var c chan int select { case x1 := <-c: fmt.Println("値: ", x1) default: fmt.Println("デフォルトケース..!") } }
出力:
デフォルト case..!