Insert & Retrieve from a channel in same main function throws "goroutine 1 [chan receive]: main.main() /path exit status 2" error

31 views Asked by At

An very new to GO & am trying to understand channels. I am trying to create a main function which will be inserting elements into a channel & printing it from the channel all in the same function. But am not able to do so without making the inserting part a separate function which is then run as a go routine. But am not able to understand why the same code wont work in a single main function in a single thread. I get the error "goroutine 1 [chan receive]: main.main() /path exit status 2".

Working Code:

package main

import (
    "fmt"
)

func inserChannel(c chan int) {
    for i := 0; i < cap(c); i++ {
        c <- i * i
    }
    defer close(c)
}

func main() {
    c := make(chan int, 10)
    go inserChannel(c)
    for i := range c {
        fmt.Println(i)
    }
}

What I am trying:

package main

import (
    "fmt"
)

func main() {
    c := make(chan int, 10)
    for i := 0; i < cap(c); i++ {
        c <- i * i
    }
    defer close(c)
    for i := range c {
        fmt.Println(i)
    }
}

I want to understand why the first will work & the second wont. It even works when I run it as a normal function i.e., not a go routine but wont if all code are in a single main function.

1

There are 1 answers

2
NubDev On

Second code:
It doesn't work because it attempts to send and receive on the channel within the same main function, without goroutines.
Reason: The for i := 0; i < cap(c); i++ loop starts sending values to the channel. When it sends the first value, it blocks, waiting for a receiver. The subsequent for i := range c loop is supposed to receive those values, but it never gets a chance to start because the first loop is already blocked. This creates a circular dependency where each operation blocks the other, leading to the deadlock and the "goroutine 1 [chan receive]: main.main() /path exit status 2" error.

The first code works because it leverages goroutines to run the sending and receiving operations concurrently. The go inserChannel(c) line launches a new goroutine that executes the inserChannel function independently. This goroutine starts sending values to the channel, allowing the main function to proceed to the for i := range c loop to receive them.