Channels
Creating and Using a Channel
make(chan Type) creates a channel that carries values of that type between goroutines. Values are sent with ch <- value and received with <-ch, and by default these operations block until the other side is ready.
Example: Creating and Using a Channel
package main
import "fmt"
func main() {
ch := make(chan string)
go func() {
ch <- "message from goroutine"
}()
msg := <-ch
fmt.Println(msg)
}
Login to try C/C++/Java/PHP code in the editor
Channels as Synchronization
Because a receive blocks until a value is sent, channels naturally synchronize goroutines -- the receiving side waits precisely until the sending goroutine has reached that point in its work.
Example: Channels as Synchronization
package main
import "fmt"
func worker(done chan bool) {
fmt.Println("working...")
done <- true
}
func main() {
done := make(chan bool)
go worker(done)
<-done
fmt.Println("worker finished, main continues")
}
Login to try C/C++/Java/PHP code in the editor
Closing a Channel
Closing a channel with close(ch) signals that no more values will be sent. Receivers can detect this with the comma-ok form, and range over a channel automatically stops when it's closed.
Note: Only the sender should close a channel -- closing a channel you're only reading from (or that's already closed) causes a panic.
Example: Closing a Channel
package main
import "fmt"
func main() {
ch := make(chan int)
go func() {
for i := 1; i <= 3; i++ {
ch <- i
}
close(ch)
}()
for v := range ch {
fmt.Println(v)
}
}
Login to try C/C++/Java/PHP code in the editor
- Sending on a channel that nobody is ever going to receive from, causing the sending goroutine to block forever (deadlock).
- Forgetting an unbuffered channel send blocks until a receiver is ready, and vice versa -- it's a rendezvous, not a mailbox.
- Reading from a closed channel expecting it to block or error, when it instead immediately returns the type's zero value.
- A channel, created with make(chan Type), lets goroutines send and receive values safely.
- Sending (ch <- v) and receiving (<-ch) on an unbuffered channel block until both sides are ready.
- Channels are the idiomatic way to synchronize and communicate between goroutines, per Go's 'share memory by communicating' philosophy.
- Reading from a closed channel returns the zero value immediately instead of blocking.
Chapter Quiz — Complete all 8 topics to unlock
0/8 topics done
Complete these topics first: