English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Golang 基礎トレーニング

Golang 制御文

Golang 関数 & メソッド

Golang 構造体

Golang 切片 & 数组

Golang 字符串(String)

Golang ポインタ

Golang インターフェース

Golang 并行

Golang 異常(Error)

Golang その他の雑項

Go Select文とdeadlock死锁

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..!