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

Golang 基础教程

Golang 控制语句

Golang 函数 & 方法

Golang 结构体

Golang 切片 & 数组

Golang 字符串(String)

Ponteiro do Golang

Interfaces do Golang

Concorrência do Golang

Exceções (Error) do Golang

Outros itens do Golang

Sentença Select do Go e deadlock

Na linguagem Go, a sentença select é comoSentença switchMas na sentença select, a declaração case se refere à comunicação, ou seja, operações de envio ou recebimento no canal.

Sintaxe:

select{
    case SendOrReceive1: // Declaração
    case SendOrReceive2: // Declaração
    case SendOrReceive3: // Declaração
    .......
    default: // Declaração
 }

Neste artigo, vamos aprender a usar o caso padrão para evitar deadlock. Mas antes disso, vamos entender o que é deadlock?

Deadlock:Quando você tenta ler ou escrever dados em um canal, mas o canal não tem valor. Portanto, ele bloqueia a execução atual da goroutine e passa o controle para outra goroutine, mas se não houver outra goroutine disponível ou se outra goroutine estiver dormindo, devido a essa situação, o programa cairá. Esse fenômeno é chamado de deadlock. Como o exemplo a seguir mostra:

package main
func main() {
    //Criar canal
    //O deadlock ocorre porque não há goroutines escrevendo
    //Portanto, a sentença select é bloqueada permanentemente
    c := make(chan int)
    select {
    case <-c:
    }
}

Saída:

erro fatal: todas as goroutines estão adormecidas - deadlock!
goroutine 1 [canal recebimento]:
main.main()

Para evitar isso, usamos o caso padrão na sentença select. Em outras palavras, quando há deadlock no programa, o caso padrão da sentença select é executado para evitar o deadlock. Como o exemplo a seguir mostra, usamos o caso padrão na sentença select para evitar o deadlock.

package main 
  
import \
  
func main() { 
  
    //Criar canal
    c := make(chan int) 
    select { 
    case <-c: 
    default: 
        fmt.Println("!.. Caso padrão...!") 
    } 
}

Saída:

!.. Caso padrão...!

Quando a sentença select tem apenas canais nil, também é permitido usar o caso padrão. Como o exemplo a seguir mostra, o canal c é nil, então é executado o caso padrão. Se o caso padrão aqui não estiver disponível, o programa ficará bloqueado permanentemente, resultando em um deadlock.

package main
import \
func main() {
    //Criar canal
    var c chan int
    select {
    case x1 := <-c:
        fmt.Println("Valor: ", x1)
    default:
        fmt.Println("Caso padrão...!")
    }
}

Saída:

Caso Padrão...!