From GopherCon 2018: Bryan C. Mills - Rethinking Classical Concurrency Patterns
1func ExampleChannelLock() {
2 mu := make(chan int, 1)
3 mu <- 0
4
5 x := <- mu
6 x = x * 2
7 mu <- x
8}()
Alternatively start with nil
inner channel for nonblocking start
(and check for nils).
1func ExampleBroadcast() {
2 bc := make(chan chan struct{}, 1)
3 bc <- make(chan struct{})
4
5 // wait
6 go func() {
7 s := <-bc
8 bc <- s
9 select {
10 case <-s:
11 }
12 }()
13
14 // signal
15 s := <-bc
16 close(s)
17 bc <- make(chan struct)
18}
less useful when you may need to recursively add work
1func ExampleSemaphore() {
2 sem := make(chan struct{}, limit)
3 for _, task := range tasks {
4 sem <- struct{}
5 go func() {
6 work(task)
7 <-sem
8 }()
9 }
10
11 // wait
12 for n := limit; n > 0; n-- {
13 sem <- struct{}
14 }
15}