3.2 KiB
title | layout |
---|---|
Go Channels | slides.html |
Go Channels
- Last time Go Synchronization
- What are channels?
- How do we use them?
Channels
- Synchronized pipes
- Buffered or Unbuffered
- Unbuffered by default
According to the Go Concurrency docs:
Channels are a typed conduit through which you can send and receive values with the channel operator,
<-
.
Creating channels
To create channels, use the builtin make function to create a typed channel:
ch := make(chan int)
Sending to channels
To send a value (or data) to a channel use the <-
operator with the channel on the left-hand side of the operands:
ch <- 1
ch <- 2
ch <- 3
Receiving from channels
Receiving from channels is similar, using the same <-
operator, but with the channel on the right-hand side of the operands:
x := <-ch
y := <-ch
z := <-ch
😈 Demo time!
Channels in detail
- Data flows in the direction of the
<-
arrow. - Must be created before use.
- Sends and receives block until the other side is ready
- Can be used as cheap synchronization
Buffered channels
- Channels can be buffered
ch := make(chan int, 100)
- Sends block only when the buffer is full
- Receives block when the buffer is empty
Example
Consider the following example:
package main
import "fmt"
func main() {
ch := make(chan int, 2)
ch <- 1
ch <- 2
fmt.Println(<-ch)
fmt.Println(<-ch)
}
What happens if you add one more send
ch <- 3
?
Iterating over channels
We can iterate over channels with the range
keyword much like slices and maps:
for x := range ch {
fmt.Printf("x: %d\n", x)
}
- The loop will continue until
ch
is closed.
Closing channels
Channels can also be closed using the builtin close function:
close(ch)
A receiver can test whether a channel has been closed:
v, ok := <-ch
- When/If
ch
is closedok
will befalse
.
Closing in detail
- Closing indicates "no more values"
- Only the sender should close a channel,
- never the receiver!
- Sending on a closed channel will
panic()
- Closing channels is optional
Waiting on channels
Finally you can wait on one or more channels by using the select
keyword and one ore more cases:
func count(x chan int) {
for {
select {
case x := <-ch
fmt.Printf("x: %d\n", x)
case <-quit:
return
}
}
}
😈 Demo time!
🎬 The End 🎬
- Create:
ch := make(chan int)
- Buffered:
ch := make(chan int, 3)
- Iterate:
for x := range ch { ... }
- Close:
close(ch)
- Closed?
v, ok := <-ch
- Ready?
select { case x := <-ch: ... }
⏭️ Next Week
Next week we'll cover:
- Goroutine Patterns