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

Golang Basic Tutorial

Golang Control Statements

Golang Function & Method

Golang Struct

Golang Slice & Array

Golang String

Golang Pointer

Golang Interface

Golang Concurrency

Golang Exception(Error)

Golang Miscellaneous

Go Select Statement and Deadlock

In Go language, the select statement is likeSwitch statementHowever, in the select statement, the case statement refers to communication, that is, the send or receive operation on the channel.

Syntax:

select{
    case SendOrReceive1: // Statement
    case SendOrReceive2: // Statement
    case SendOrReceive3: // Statement
    .......
    default: // Statement
 }

In this article, we will learn how to use the default case to avoid deadlocks. But first, we need to understand what deadlock is?

Deadlock:When you try to read or write data from a channel but there is no value in the channel. Therefore, it blocks the current execution of the goroutine and passes control to other goroutines, but if there are no other goroutines available or other goroutines are sleeping due to this situation, the program will crash. This phenomenon is called a deadlock. As shown in the following example:

package main
func main() {
    //Create a channel
    //Deadlock occurs because there is no goroutine writing
    //Therefore, the select statement is blocked forever
    c := make(chan int)
    select {
    case <-c:
    }
}

Output:

fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()

To avoid this situation, we use the default case in the select statement. In other words, when a deadlock occurs in the program, the default case of the select statement is executed to avoid the deadlock. As shown in the following example, we use the default case in the select statement to avoid the deadlock.

package main 
  
import \
  
func main() { 
  
    //Create a channel
    c := make(chan int) 
    select { 
    case <-c: 
    default: 
        fmt.Println("!.. Default case...!") 
    } 
}

Output:

!.. Default case...!

When the select statement only has a nil channel, the default case is also allowed. As shown in the following example, channel c is nil, so the default case is executed. If the default case here is not available, the program will be blocked forever, and a deadlock will occur.

package main
import \
func main() {
    //Create a channel
    var c chan int
    select {
    case x1 := <-c:
        fmt.Println("Value: ", x1)
    default:
        fmt.Println("Default case...!")
    }
}

Output:

Default case...!