Table of contents
1.
Introduction
2.
Select Statement in Go
2.1.
Example
2.2.
Output
3.
Deadlock in Go
3.1.
Example
3.2.
Output
4.
Handling Deadlock with Default Case
4.1.
Code
4.2.
Output
5.
Frequently Asked Questions
5.1.
Why is Golang so faster?
5.2.
Is the Golang programming language multithreaded?
5.3.
What are packages in Golang?
5.4.
 
5.5.
Is Golang appropriate for coding interviews?
6.
Conclusion
Last Updated: Mar 27, 2024
Easy

Go Deadlock and Select Statement

Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Go is an open-source programming language aimed at being simple, reliable, and efficient. It is a compiled and statically typed general-purpose programming language with a simple syntax and extensive standard libraries. It has a select statement, which is similar to a switch statement. However, the case statement in the select statement refers to communication.

But do you know that we can handle deadlock conditions using the default case in the select statement?

This article will discuss the interesting concept of using the default case in select statements to handle deadlock. Let’s get started by discussing the basics of deadlock.

Select Statement in Go

The select statement is a fundamental conditional statement in Go programming. Like a switch statement in another programming language, the select statement allows us to choose or execute one expression out of many. The primary distinction between switch and select is that select operates on the wait principle, which will not run until the communication is complete. The term "communication" refers to sending and receiving data over any particular channel; once the communication is complete, the next check is performed, demonstrating that the select statement in the Go language is entirely dependent on the channel.

Let’s look at the syntax of the select statement given below.

select {
        case send-channel-1 <- receive-channel-1:
            //some expression for send-channel-1
        case send-channel-2 <- receive-channel-2:
            //some expression for send-channel-2
        default:
            //some expression for default
    }

Select is a built-in statement in the Go programming language, and we don't need to import any packages to use it. We're passing the various send and receive statements after the select statement, which means each is a type of goroutine, and we know that goroutines work on the send and receive principle.

Example

In the below example, we have shown how to select one condition from numerous statements, allowing us to manage a variety of situations.

//Example of select statement
package main    
import "fmt"
func main() {
    c1 := make(chan string)
    c2 := make(chan string)
    //send
    go func() {
        c1 <- "one"
    }()
    go func() {
        c2 <- "two"
    }()
    //receive
    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-c1:
            fmt.Println("received", msg1)
        case msg2 := <-c2:
            fmt.Println("received", msg2)
        default:
            fmt.Println("no value received")
        }
    }
}

Output

We can see that we got the desired output of the above program, which prints the respective values returned by the functions.

Deadlock in Go

Before introducing the concept of Go deadlock, we strongly recommend you go through our article on “Go Routines.” The article covers the fundamentals of “channels” and the “waiting” concept of Go programming.

Let’s start by understanding what deadlock is and when it happens. A deadlock occurs when a set of goroutines are waiting for each other, and none can move forward.

For instance, a deadlock occurs when a goroutine attempts to receive a message from an empty channel and has no other goroutines active. The "Receiver" goroutine, in this case, never receives a message.

Example

Below is the implementation of a deadlock situation where there is no sender. Please look at the code below to have a clear understanding of the deadlock situation.

//example of deadlock in Go due to no sender
package main
import "fmt"
func main() {
    c := make(chan int)
    select {
    case <-c: // this case will never be selected because of deadlock
        fmt.Println("received") // this will never be printed
    }
}

The program will become stuck in the channel sending process, waiting for someone to read the value for a lifetime. Go can detect instances like these in real-time. The following is the output of our programme.

Output

We can see that the program throws a fatal error message about the deadlock situation. Now, in the next section, let's see how we can handle this situation using the default case of the select statement.

Handling Deadlock with Default Case

In the above section, we understood how the deadlock situation arises in Go programming. Now, we will see how we can handle this deadlock situation. We employ a default case in the select statement to avoid this scenario. In other words, if the programme encounters a deadlock, the default case of the select statement is used to prevent the deadlock. 

To avoid deadlock, we use a default case in the choose statement, as illustrated below.

Code

//handling deadlock in Go with Default case in Select statement
package main
import "fmt"
func main() {
    c := make(chan int)
    select {
    case <-c: // this case will never be selected because of deadlock
        fmt.Println("received") // this will never be printed
    default: //default case is executed if no other case is selected
        fmt.Println("default case...")
    }
}

We can see that the default case should be executed in this case because no other case is selected. Here, the deadlock occurs because channel “c” is not closed. Let’s look at the output below.

Output

As expected, we can see that the output is the default case because no other case is selected.

Frequently Asked Questions

Why is Golang so faster?

Go is a very fast language. Go will automatically outperform interpreted or virtual runtime languages because it is compiled to machine code. Go applications are also incredibly fast to compile, and the final binary is very compact.
 

Is the Golang programming language multithreaded?

Goroutines allow for multi-threaded concurrency and parallelization, and goroutines work asynchronously, allowing for efficient use of both multi-threading and asynchronous programming.
 

What are packages in Golang?

Go Packages (abbreviated as pkg) are directories in the Go workspace containing Go source files or other Go packages. From variables to functions, every piece of code is written in source files, which are then linked into a package. A package should be assigned to each source file.

The basic syntax to declare a package is as follows:

package <package_name>

 

Is Golang appropriate for coding interviews?

The answer is a straightforward “Yes.” Golang is supported by most code-sharing platforms that corporations use these days for interviews. Most organisations will let you code in your chosen language if you are not applying for senior or mid-senior level positions that need proficiency in a specific language. If Go is your preferred language, go ahead and use it!

Conclusion

This article extensively discussed the basics of deadlock and select statements in Go. We implemented the programme to demonstrate how to avoid the deadlock situation in Go programming by using the default case in the select statement.

We hope this blog has helped you enhance your knowledge regarding “Go Deadlock and Select Statement.” If you would like to learn more, check out our articles on “Go Loops,” “Returning Pointer from a Function in Go,” “Pointer to an Array as Function Argument in Go,” “Defer in Go,” and “Go Routines.” Do upvote our blog to help other ninjas grow.

Head over to our practice platform Coding Ninjas Studio to practice top problems, attempt mock tests, read interview experiences, interview bundle, follow guided paths for placement preparations and much more!

Happy Reading!

Live masterclass