The document discusses channels in Go. It defines a channel as a mechanism for concurrently executing functions to communicate by sending and receiving values. It then discusses what happens when reading from or writing to a closed channel, how channels are implemented internally using a circular buffer and lock, and provides code examples demonstrating channel usage and closing. It also includes quotes about communicating between goroutines via channels instead of sharing memory.
2. 2
Private & Confidential 2
What is Channel
”
A channel provides a mechanism for
concurrently executing functions to
communicate by sending and receiving values
of a specified element type.
-- Golang Spec (//golang.org/ref/spec#Channel_types)
3. 3
Private & Confidential 3
What behind Channel
QWhat will happen if read from/write to
a closed channel?
4. 4
Private & Confidential 4
<- Closed Channel <-
What behind Channel
x, ok := <- chan
- [unread data] x is remaining value, ok is true
- [has been read] x is falsy value, ok is false
- [empty] x is falsy value, ok is false
5. 5
Private & Confidential 5
<- Closed Channel <-
What behind Channel
panic
x, ok := <- chan
- [unread data] x is remaining value, ok is true
- [has been read] x is falsy value, ok is false
- [empty] x is falsy value, ok is false
chan <- x
6. 6
Private & Confidential 6
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
7. 7
Private & Confidential 7
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c
<- c
close(c)
<- c
<- c
c <- 14
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
8. 8
Private & Confidential 8
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c
<- c
close(c)
<- c
<- c
c <- 14
buf (doubly circular linked list)
lock
11
12
13
14
goroutine
sendx
recvx
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
9. 9
Private & Confidential 9
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c
<- c
close(c)
<- c
<- c
c <- 14
buf (doubly circular linked list)
lock
goroutine
sendx
recvx
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
11
12
13
14
10. 10
Private & Confidential 10
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c
<- c
close(c)
<- c
<- c
c <- 14
11
lock
goroutine buf (doubly circular linked list)
sendx
recvx
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
12
13
14
11. 11
Private & Confidential 11
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c
<- c
close(c)
<- c
<- c
c <- 14
11
lock
goroutine buf (doubly circular linked list)
sendx
recvx
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
12
13
14
12. 12
Private & Confidential 12
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c
<- c
close(c)
<- c
<- c
c <- 14
11
lock
goroutine buf (doubly circular linked list)
sendx
recvx
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
12
13
14
13. 13
Private & Confidential 13
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c
<- c
close(c)
<- c
<- c
c <- 14
11 12
lock
goroutine buf (doubly circular linked list)
sendx
recvx
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
13
14
14. 14
Private & Confidential 14
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c
<- c
close(c)
<- c
<- c
c <- 14
11 12
lock
goroutine buf (doubly circular linked list)
sendx
recvx
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
13
14
15. 15
Private & Confidential 15
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c
<- c
close(c)
<- c
<- c
c <- 14
11 12
lock
goroutine buf (doubly circular linked list)
sendx
recvx
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
13
14
16. 16
Private & Confidential 16
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c
<- c
close(c)
<- c
<- c
c <- 14
11 12
13
lock
goroutine buf (doubly circular linked list)
sendx
recvx
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
14
17. 17
Private & Confidential 17
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c
<- c
close(c)
<- c
<- c
c <- 14
11 12
13
lock
goroutine buf (doubly circular linked list)
sendx
recvx
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
14
18. 18
Private & Confidential 18
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c
<- c
close(c)
<- c
<- c
c <- 14
11 12
13
lock
goroutine buf (doubly circular linked list)
sendx
recvx
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
14
19. 19
Private & Confidential 19
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c // 11
<- c
close(c)
<- c
<- c
c <- 14
12
13
lock
goroutine buf (doubly circular linked list)
sendx
recvx
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
14
11
20. 20
Private & Confidential 20
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c // 11
<- c
close(c)
<- c
<- c
c <- 14
12
13
lock
goroutine buf (doubly circular linked list)
sendx
recvx
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
14
11
21. 21
Private & Confidential 21
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c // 11
<- c
close(c)
<- c
<- c
c <- 14
12
13
goroutine buf (doubly circular linked list)
sendx
recvx
lock
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
14
11
22. 22
Private & Confidential 22
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c // 11
<- c // 12
close(c)
<- c
<- c
c <- 14
13
lock
goroutine buf (doubly circular linked list)
sendx recvx
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
14
11
12
23. 23
Private & Confidential 23
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c // 11
<- c // 12
close(c)
<- c
<- c
c <- 14
13
goroutine buf (doubly circular linked list)
sendx recvx
lock
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
14
11
12
24. 24
Private & Confidential 24
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c // 11
<- c // 12
close(c)
<- c // 13
<- c
c <- 14
goroutine buf (doubly circular linked list)
sendx
recvx
lock
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
14
11
12
13
25. 25
Private & Confidential 25
What behind Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c // 11
<- c // 12
close(c)
<- c // 13
<- c // 0
c <- 14
goroutine buf (doubly circular linked list)
sendx
recvx
lock
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
14
11
12
13
26. 26
Private & Confidential 26
What behind Channel
c := make(chan int, 4)
c <- 11
c <- 12
c <- 13
<- c
<- c
close(c)
<- c
<- c
c <- 14
panic: send on closed channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
goroutine buf (doubly circular linked list)
sendx
recvx
lock
type hchan struct {
// points to an array of
dataqsiz elements
buf unsafe.Pointer
// send index
sendx uint
// receive index
recvx uint
// lock protects all fields
in hchan
lock mutex
...
}
27. 27
Private & Confidential 27
chan <- x
<- Closed Channel <-
What behind Channel
panic
x, ok := <- chan
- [unread data] x is remaining value, ok is true
- [has been read] x is falsy value, ok is false
- [empty] x is falsy value, ok is false
28. 28
Private & Confidential 28
What behind Channel
”
Do not communicate by sharing memory;
instead, share memory by communicating.
-- Someone else
memory
goroutine
goroutine
goroutine
memory memory
29. 29
Private & Confidential 29
What behind Channel
”
Do not communicate by sharing memory;
instead, share memory by communicating.
-- Someone else
memory
goroutine
goroutine
goroutine
memory memory
30. 30
Private & Confidential 30
What behind Channel
”
Do not communicate by sharing memory;
instead, share memory by communicating.
-- Someone else
memory
goroutine
goroutine
goroutine
memory memory
31. 31
Private & Confidential 31
What behind Channel
”
Do not communicate by sharing memory;
instead, share memory by communicating.
-- Someone else
memory
goroutine
goroutine
goroutine
memory memory
34. 34
Private & Confidential 34
type hchan struct {
// list of send waiters
sendq waitq
// list of recv waiters
recvq waitq
buf unsafe.Pointer
sendx uint
recvx uint
lock mutex
...
}
What crashes Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
buf (doubly circular linked list)
lock
sendx
recvx
11 12
14 13
35. 35
Private & Confidential 35
type hchan struct {
// list of send waiters
sendq waitq
// list of recv waiters
recvq waitq
buf unsafe.Pointer
sendx uint
recvx uint
lock mutex
...
}
What crashes Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
buf (doubly circular linked list)
lock
sendx
recvx
11 12
14 13
sendq
recvq
36. 36
Private & Confidential 36
type hchan struct {
// list of send waiters
sendq waitq
// list of recv waiters
recvq waitq
buf unsafe.Pointer
sendx uint
recvx uint
lock mutex
...
}
What crashes Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
buf (doubly circular linked list)
lock
scheduling
sendx
recvx
11 12
14 13
sendq
recvq
37. 37
Private & Confidential 37
type hchan struct {
// list of send waiters
sendq waitq
// list of recv waiters
recvq waitq
buf unsafe.Pointer
sendx uint
recvx uint
lock mutex
...
}
What crashes Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
buf (doubly circular linked list)
lock
scheduling
sendx
recvx
11 12
14 13
sendq
recvq
c <- 15
goroutine
38. 38
Private & Confidential 38
type hchan struct {
// list of send waiters
sendq waitq
// list of recv waiters
recvq waitq
buf unsafe.Pointer
sendx uint
recvx uint
lock mutex
...
}
What crashes Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
buf (doubly circular linked list)
lock
scheduling
sendx
recvx
11 12
14 13
sendq
recvq
c <- 15
goroutine
39. 39
Private & Confidential 39
type hchan struct {
// list of send waiters
sendq waitq
// list of recv waiters
recvq waitq
buf unsafe.Pointer
sendx uint
recvx uint
lock mutex
...
}
What crashes Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
buf (doubly circular linked list)
lock
scheduling
sendx
recvx
11 12
14 13
sendq
recvq
c <- 15
goroutine
<- c
goroutine
40. 40
Private & Confidential 40
type hchan struct {
// list of send waiters
sendq waitq
// list of recv waiters
recvq waitq
buf unsafe.Pointer
sendx uint
recvx uint
lock mutex
...
}
What crashes Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
buf (doubly circular linked list)
lock
scheduling
sendx
recvx
11 12
14 13
sendq
recvq
c <- 15
goroutine
<- c
goroutine
41. 41
Private & Confidential 41
type hchan struct {
// list of send waiters
sendq waitq
// list of recv waiters
recvq waitq
buf unsafe.Pointer
sendx uint
recvx uint
lock mutex
...
}
What crashes Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
buf (doubly circular linked list)
lock
scheduling
recvx
sendx
12
14 13
sendq
recvq
c <- 15
goroutine
<- c
// 11
goroutine
42. 42
Private & Confidential 42
type hchan struct {
// list of send waiters
sendq waitq
// list of recv waiters
recvq waitq
buf unsafe.Pointer
sendx uint
recvx uint
lock mutex
...
}
What crashes Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
buf (doubly circular linked list)
scheduling
12
14 13
sendq
recvq
c <- 15
goroutine
<- c
// 11
goroutine
lock
recvx
sendx
43. 43
Private & Confidential 43
type hchan struct {
// list of send waiters
sendq waitq
// list of recv waiters
recvq waitq
buf unsafe.Pointer
sendx uint
recvx uint
lock mutex
...
}
What crashes Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
buf (doubly circular linked list)
scheduling
12
14 13
sendq
recvq
c <- 15
goroutine
lock
recvx
sendx
44. 44
Private & Confidential 44
type hchan struct {
// list of send waiters
sendq waitq
// list of recv waiters
recvq waitq
buf unsafe.Pointer
sendx uint
recvx uint
lock mutex
...
}
What crashes Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
buf (doubly circular linked list)
scheduling
12
14 13
sendq
recvq
c <- 15
goroutine
lock
recvx
sendx
45. 45
Private & Confidential 45
type hchan struct {
// list of send waiters
sendq waitq
// list of recv waiters
recvq waitq
buf unsafe.Pointer
sendx uint
recvx uint
lock mutex
...
}
What crashes Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
buf (doubly circular linked list)
scheduling
12
14 13
sendq
recvq
c <- 15
goroutine
lock
recvx
sendx
46. 46
Private & Confidential 46
type hchan struct {
// list of send waiters
sendq waitq
// list of recv waiters
recvq waitq
buf unsafe.Pointer
sendx uint
recvx uint
lock mutex
...
}
What crashes Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
buf (doubly circular linked list)
scheduling
sendx
recvx
15 12
14 13
sendq
recvq
goroutine
lock
47. 47
Private & Confidential 47
type hchan struct {
// list of send waiters
sendq waitq
// list of recv waiters
recvq waitq
buf unsafe.Pointer
sendx uint
recvx uint
lock mutex
...
}
What crashes Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
buf (doubly circular linked list)
scheduling
15 12
14 13
sendq
recvq
goroutine
lock
sendx
recvx
48. 48
Private & Confidential 48
type hchan struct {
// list of send waiters
sendq waitq
// list of recv waiters
recvq waitq
buf unsafe.Pointer
sendx uint
recvx uint
lock mutex
...
}
What crashes Channel
https://github.com/golang/go/blob/master/src/runtime/chan.go#L32
buf (doubly circular linked list)
scheduling
15 12
14 13
sendq
recvq
lock
sendx
recvx
49. 49
Private & Confidential 49
1. communication between goroutine
2. multiplexing
3. timeout handling
4. range channel
5. read-only/write-only channel
When uses Channel
50. 50
Private & Confidential 50
func main() {
var c chan int
go func() {
c <- 1
}()
<-c
}
1. communication between goroutine
2. multiplexing
3. timeout handling
4. range channel
5. read-only/write-only channel
When uses Channel
51. 51
Private & Confidential 51
for {
select {
case x, ok := <-c1:
...
case x, ok := <-c2:
...
default:
...
}
}
1. communication between goroutine
2. multiplexing
3. timeout handling
4. range channel
5. read-only/write-only channel
When uses Channel
52. 52
Private & Confidential 52
select {
case <- c:
// get from channel c
case <- time.After(2 * time.Second)
// timeout when getting from channel c
}
When uses Channel
1. communication between goroutine
2. multiplexing
3. timeout handling
4. range channel
5. read-only/write-only channel
53. 53
Private & Confidential 53
1. communication between goroutine
2. multiplexing
3. timeout handling
4. range channel
5. read-only/write-only channel
When uses Channel
func consumer(c chan int) {
for x := range c {
...
}
}
func producer(c chan int) {
for _, x := range values {
c <- x
}
}
54. 54
Private & Confidential 54
// usually used for declaration
func foo(ch chan<- int) <-chan int {
...
}
When uses Channel
1. communication between goroutine
2. multiplexing
3. timeout handling
4. range channel
5. read-only/write-only channel