A Go channel is a typed path for sending values between goroutines. Create one with `make(chan int)`, send with `c <- value`, and receive with `value := <-c`. An unbuffered send waits for a receiver, so the handoff also synchronizes the goroutines. Channels can carry structured data without marshaling it into bytes. section 1.2.3 section 5.3 section 5.3.3
Send values and finish cleanly
For a finite stream, let the sender close the channel after its last send. The receiver checks whether each receive succeeded: package main import "fmt" func main() { messages := make(chan string) go func() { messages <- "ready" messages <- "done" close(messages) }() for { message, ok := <-messages if !ok { return } fmt.Println(message) } } Do not close a channel while another goroutine may still send to it: sending on a closed channel panics. In a long-running sender, a separate `done` channel can communicate that it is time to stop and close the message channel. section 1.2.3 section 5.3.2
Use a buffer when a send must proceed before a receiver is ready: `make(chan bool, 1)` has room for one value. That capacity also makes a simple lock possible. Send to acquire it; receive to release it. Another goroutine trying to send while the buffer is full waits. An unbuffered channel cannot serve this pattern because its first send would wait for a receive. section 5.3.3
Listing 5.11 Simple locking with channels
package main
import (
"log"
"time"
)
func main() {
lock := make(chan bool, 1) // #1
for i := 1; i < 7; i++ { // #2
go worker(i, lock) // #2
}
time.Sleep(10 * time.Second)
}
func worker(id int, lock chan bool) {
log.Printf("%d wants the lock\n", id)
lock <- true // #3
log.Printf("%d has the lock\n", id) // #4
<-lock // #5
log.Printf("%d is releasing the lock\n", id)
}
The complete worker example shares a one-slot channel among goroutines and shows each worker acquiring and releasing the lock. section 5.3.3
Channels also carry control signals, not just application data. A signal channel can receive an operating-system interrupt while a server runs concurrently; after receiving the signal, the program can request a graceful shutdown. If other goroutines must finish too, coordinate them separately. section 2.3.2









