Golang | Deadlock and Default Case in Select Statement

In Go language, the select statement is just like a switch statement, but in the select statement, the case statement refers to communication, i.e. sent or receive operation on the channel.

Syntax:

select{

case SendOrReceive1: // Statement
case SendOrReceive2: // Statement
case SendOrReceive3: // Statement
.......
default: // Statement

In this article, we learn how the default case is used to avoid deadlock. But first, we learn what is a deadlock?



Deadlock: When you trying to read or write data from the channel but the channel does not have value. So, it blocks the current execution of the goroutine and passes the control to other goroutines, but if there is no other goroutine is available or other goroutines are sleeping due to this situation program will crash. This phenomenon is known as deadlock. As shown in the below example:

Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

// Go program to illustrate
// how deadlock arises
package main
  
// Main function
func main() {
  
    // Creating a channel
    // Here  deadlock arises because
    // no goroutine is writing
    // to this channel so, the select 
    // statement has been blocked forever
    c := make(chan int)
    select {
    case <-c:
    }
}

chevron_right


Output:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()

To avoid this situation we use a default case in the select statement. Or in other words, when the deadlock arises in the program, then default case of the select statement executed to avoid deadlock. As shown in the below example, we use a default case in the select statement to avoid deadlock.

Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

// Go program to illustrate how to resolve
// the deadlock problem using the default case
package main
  
import "fmt"
  
// Main function
func main() {
  
    // Creating a channel
    c := make(chan int)
    select {
    case <-c:
    default:
        fmt.Println("!.. Default case..!")
    }
}

chevron_right


Output:

!.. Default case..!

You are also allowed to use default case when the select statement has only nil channel. As shown in the below example, channel c is nil, so default case executed if here default case is not available, then the program will be blocked forever and deadlock arises.

Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

// Go program to illustrate
// the execution of default case
package main
  
import "fmt"
  
// Main function
func main() {
  
    // Creating a channel
    var c chan int
  
    select {
    case x1 := <-c:
        fmt.Println("Value: ", x1)
    default:
        fmt.Println("Default case..!")
    }
}

chevron_right


Output:

Default case..!


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.