Hit deadlock when Select channel

Issue

package main

import (
    "fmt"
    "time"
)

func Server1(ch chan string) {
    time.Sleep(2*time.Second)
    ch <- "from Server-1"
}

func Server2(ch chan string) {
    time.Sleep(3*time.Second)
    ch <- "from Server-2"
}

func main() {
    input1 := make(chan string)
    input2 := make(chan string)
    
    go Server1(input1)
    go Server2(input2)
    
    for {
        select {
            case s1 := <- input1:
                fmt.Printf(s1 + "\n")
            case s2 := <- input2:
                fmt.Printf(s2 + "\n")   
        }
    }
}

Ran the above code, get errors as following

from Server-1
from Server-2
fatal error: all goroutines are asleep - deadlock!

In this channel select, we have two threads running with different timer interval, Why is it a deadlock?

Solution

You launch 2 goroutines that only send a single value on their channel, then they will terminate, so the main function will be left there hanging alone. That’s why the deadlock.

If you modify Server1() and Server2() to send values endlessly, it won’t be a deadlock:

func Server1(ch chan string) {
    for {
        time.Sleep(2 * time.Second)
        ch <- "from Server-1"
    }
}

func Server2(ch chan string) {
    for {
        time.Sleep(3 * time.Second)
        ch <- "from Server-2"
    }
}

Answered By – icza

Answer Checked By – Willingham (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.