The Go Programming Language Specification
Close
For a channel c, the built-in function close(c) records that no more values will be sent on the channel. After calling close, and after any previously sent values have been received, receive operations will return the zero value for the channel's type without blocking.
In the channel buffer there are 5 previously sent values followed by a close.
For example,
package main
import (
"fmt"
"sync"
"time"
)
func main() {
iCh := make(chan int, 99)
var wg sync.WaitGroup
go func() {
for i := 0; i < 5; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
iCh <- i
}(i)
}
wg.Wait()
close(iCh)
}()
time.Sleep(5 * time.Second)
fmt.Println("previously sent values", len(iCh))
for i := range iCh {
fmt.Printf("%v\n", i)
}
print("the channel should be closed by now\n")
print("done")
}
Output:
previously sent values 5
0
1
2
3
4
the channel should be closed by now
done
Answer from peterSO on Stack OverflowHow to check is a channel is closed before writing into it.
builtin: description of close behavior of reading from closed channel is vague
Short Read: Closing a closed channel in Go, can result in disaster
Panic: send on closed channel
In the given code, I have closed a channel in generateOne and then used the same channel in the next function to write on. This will panic with a message send on closed channel. Can anyone tell me how I can make sure if the channel is closed or not before sending any data?
Note: This is a Unidirectional channel.
package main
import "time"
func generateOne(a chan<- int) {
for i := 0; i < 10; i++ {
a <- i
}
close(a)
}
func generateTwo(a chan<- int) {
for {
a <- 10
}
}
func consume(a <-chan int) {
for {
data, ok := <-a
if ok == false {
break
}
println(data)
}
}
func main() {
a := make(chan int)
go generateOne(a)
go generateTwo(a)
go consume(a)
time.Sleep(1 * time.Second)
}Hello there,
I have a channel chan error with a reading and writing goroutines using it. It is known in advance the writing goroutine writes to it only once then closes it. Should the reader goroutine read the error from the channel and then read again the channel closing to drain it? Or is there no need (resource usage wise) to drain a closed channel?
Code example (as requested):
ch := make(chan int)
go func(writeCh chan<- int) {
writeCh <- 1
close(writeCh)
}(ch)
go func(readCh <-chan int) {
_ = <-readCh // read the 1
_ = <-readCh // should I drain the channel??
}(ch)Thanks!