gosynchronizationdeadlockgoroutine

why I am not getting deadlock


I was revising the concepts of the channels in go where I learned in the unbuffered channel if the receivers are less but senders are more then It must give deadlock and vice versa

In my case first part is not working I want to get deadlock if the senders are more but receivers are less. I have set the main goroutine waiting time for 5 seconds still...

According to this source here and here

my examples

not getting deadlock here senders more receiver less

package main

import (
    "fmt"
    "time"
)

func worker(done chan bool) {
    fmt.Print("working...")
    time.Sleep(time.Second)
    fmt.Println("done")

    done <- true // This must block if no receiver is ready
}

func main() {
    done := make(chan bool) // unbuffered

    for i := 0; i < 5; i++ {
        go worker(done) 
    }

    <-done 
    <-done 
    <-done 

    time.Sleep(5*time.Second)
}

and this is working perfectly (giving deadlock - sender less receivers more)

package main

import (
    "fmt"
    "time"
)

func worker(done chan bool) {
    fmt.Print("working...")
    time.Sleep(time.Second)
    fmt.Println("done")

    done <- true // This must block if no receiver is ready
}

func main() {
    done := make(chan bool) // unbuffered

    for i := 0; i < 5; i++ {
        go worker(done) 
    }

    <-done 
    <-done 
    <-done 
    <-done 
    <-done 
    <-done 

    time.Sleep(5*time.Second)
}

Solution

  • As per the language specification:

    Program execution begins by initializing the program and then invoking the function main in package main. When that function invocation returns, the program exits. It does not wait for other (non-main) goroutines to complete.

    In your "not getting deadlock" example you are:

    Three of the go routines will send successfully (and exit), the others will be blocked. However, once the three receives have completed main returns, and the program execution ends (the fact that goroutines are still running is irrelevant).

    In your second example the blocking receive is within main, this means that main does not return and you have a deadlock.

    Note that you will not get a deadlock whilst waiting on time.Sleep (as this will return the code is not deadlocked).