If you’re using channel looping (for i := range ch), you need to close the channel once you’re done with it from the sender side. In your subroutine, you passed the value into the channel and sleep. So, a proper correction should be:
...
go func() {
ch <- i
i++
time.Sleep(time.Second * 2)
close(ch)
}
...
EDIT:
Reason: main waits forever
the main is continuously waiting for channel to be closed in order to proceed with the range safely. However, instead of getting close signal, the goroutine ended instead, making the for loop wait forever (deadlock waiting). That’s why you’re getting the deadlock.
2. Site Note: Bad Code
in your for loop, println(i) is an unknown function. Should it be fmt.Println(i)?
Cross check
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int, 10)
i := 100
go func() {
ch <- i
i++
time.Sleep(time.Second * 2)
close(ch)
}()
for i := range ch {
fmt.Println(i)
}
fmt.Println("[ END ]")
}
// Output:
// 100
// [ END ]
I want to repeatdly send some values(100,101,102 … N) but, your code will be done after sending only one time. How can I construct receiver(range loop) and sender(go-routine)?
That, you can start with concurrency planning with crisp and clear data transfers. You can use flow chart or pseudo-code. Here’s one example using pseudo-code:
Process 0 (main):
make channel with 10 buffer space
set my i limit to 100.
start p1 process.
start reading from channel until it closed.
terminate entire program.
Process 1 (let’s name it p1):
loop from 0 to limit, named value
for each value, send value to channel then sleep for 2 seconds
close channel once done.
terminate p1 process.
Keywords:
must be clear with ***WHO does WHAT at WHEN***, every single step for every processes.
You can try it out on your own. I re-coded the example to match the pseudo-code so be self-disciplined over there, all right?
An example answer:
package main
import (
"fmt"
"time"
)
func p1(limit int, ch chan int) {
for value := 0; value < limit; value++ {
ch <- value
time.Sleep(time.Second * 2)
}
// done with operation, close channel.
close(ch)
}
func main() {
ch := make(chan int, 10)
i := 100
// start p1 process
go p1(i, ch)
// read from channel
for i := range ch {
fmt.Println(i)
}
fmt.Println("[ END ]")
}