Go channels synchronize goroutines while transferring typed values. Sending or receiving may block, so channel ownership, closure, buffering, cancellation, and the number of participants must be designed together.
An unbuffered send completes only when a receiver is ready, creating a synchronization point. A buffered channel allows sends until capacity is full and receives until it is empty. Buffering absorbs a bounded mismatch; it does not remove the need for backpressure or cancellation.
The goroutine that knows no more values will be sent should close the channel. Receivers normally do not close it, and a channel does not need closing merely to release memory. Sending to a closed channel panics; receiving returns queued values and then the zero value with ok false.
Range over a channel ends only after closure, so an unclosed producer can leave consumers blocked forever. Nil channels block forever on send and receive and can be enabled or disabled deliberately inside select.
select waits until one communication case can proceed. Include context cancellation for request-scoped work and ensure every worker can stop even when downstream consumers leave. A default case makes select non-blocking and can create busy loops if used without pacing.
Use timers carefully and stop or reuse them in repeated loops. Timeouts are failure policy, not a substitute for fixing leaked goroutines or an unbounded workload.
A worker pool needs a bounded job source, defined result collection, cancellation, and a WaitGroup or equivalent completion rule. Close result channels only after every producer finishes. In pipelines, each stage must stop sending when the next stage cancels, or blocked sends leak goroutines.
func worker(ctx context.Context, jobs <-chan int, results chan<- int) {
for {
select {
case <-ctx.Done():
return
case job, ok := <-jobs:
if !ok {
return
}
select {
case results <- job * job:
case <-ctx.Done():
return
}
}
}
}
values := make(chan int, 2)
values <- 10
values <- 20
close(values)
for value := range values {
fmt.Println(value)
}
No. Close only when receivers need a no-more-values signal. Garbage collection does not require explicit channel closure.
Yes, but one coordinator must determine when all senders are finished before closing the channel.
Practice, interview questions, and compiler links for Go Channels.
Finish the concept here, then reinforce it with hands-on coding, interview prep, or a tool that matches the topic.
Explore 500+ free tutorials across 20+ languages and frameworks.
Fresh tutorials, interview guides, and coding practice in your inbox.