Jon
Jon

Reputation: 13

When I don't use the go keyword a function doesn't work

In this function you can see that I use the go keyword.

package main

import (
    "fmt"
    "math"
)

func main() {
    c := make(chan string)
    go findGreatestDivisor(4, c)
    for i := 0; i <= 1; i++ {
        fmt.Println(<-c)
    }
}

func findGreatestDivisor(num float64, c chan string) {
    var counter float64 = 10000
    for i := 9999; i > 0; i-- {
        if math.Mod(num, counter) == 0 {
            fmt.Println("Check..", math.Mod(4, 1))
            c <- fmt.Sprintf("%f is divisble by %d", num, i)
        }
        counter--
    }

}

It works. It gives me the largest integer. But now I get curious and delete the go keyword where I called the function here

go findGreatestDivisor(4,c)

When i just do

findGreatestDivisor(4,c)

it gives me the error

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]: main.findGreatestDivisor(0x4010000000000000,
0xc82001a0c0)
       /home/ubuntu/workspace/test.go:21 +0x37c main.main()
       /home/ubuntu/workspace/test.go:10 +0x61 exit status 2

Why is that?

Upvotes: 0

Views: 88

Answers (1)

peterSO
peterSO

Reputation: 166785

The Go Programming Language Specification

Send statements

A send statement sends a value on a channel. The channel expression must be of channel type, the channel direction must permit send operations, and the type of the value to be sent must be assignable to the channel's element type.

SendStmt = Channel "<-" Expression .
Channel  = Expression .

Both the channel and the value expression are evaluated before communication begins. Communication blocks until the send can proceed. A send on an unbuffered channel can proceed if a receiver is ready. A send on a buffered channel can proceed if there is room in the buffer. A send on a closed channel proceeds by causing a run-time panic. A send on a nil channel blocks forever.

ch <- 3  // send value 3 to channel ch

In findGreatestDivisor

c := make(chan string)
findGreatestDivisor(4,c)

you try to send on the unbuffered channel c

c <- fmt.Sprintf("%f is divisble by %d", num, i)

but communication blocks until the send can proceed. A send on an unbuffered channel can proceed if a receiver is ready. There is no receiver ready.

The receives on channel c

fmt.Println(<-c)

won't be ready until after you return from findGreatestDivisor. That's too late.

Upvotes: 2

Related Questions