1
votes

I am trying to understand the difference between calling goroutine with/without anonymous function. When I try below code with anonymous function it works.

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int)

    go func() {
      fmt.Println(<-ch)
    }() 
    go send(1, ch)      

    time.Sleep(100 * time.Millisecond)
}

Below code without a anonymous function fails with deadlock.

go fmt.Println(<-ch) //fatal error: all goroutines are asleep - deadlock!

The code is available here

1

1 Answers

3
votes

The Go Programming Language Specification

Receive operator

For an operand ch of channel type, the value of the receive operation <-ch is the value received from the channel ch. The channel direction must permit receive operations, and the type of the receive operation is the element type of the channel. The expression blocks until a value is available.


For example,

package main

import "fmt"

func main() {
    ch := make(chan int)
    go fmt.Println(<-ch)
    ch <- 1
}

Playground: https://play.golang.org/p/K3_V92NRWvY

Output:

fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
    // At prog.go: line 7: (<-ch)

fmt.Println(<-ch) evaluates its arguments, a receive on ch. There is no send pending for ch. fmt.Println(<-ch) blocks until a value is available, which never happens, it never gets to ch <- 1.


It is equivalent to:

package main

import "fmt"

func main() {
    ch := make(chan int)
    arg := <-ch
    go fmt.Println(arg)
    ch <- 1
}

Playground: https://play.golang.org/p/1wyVTe-8tyB

Output:

fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
    // At prog.go: line 7: arg := <-ch