SEANK.H.LIAO

go channel sync

using channels in place of other directives

Synchronization

From GopherCon 2018: Bryan C. Mills - Rethinking Classical Concurrency Patterns

exclusive access

1func ExampleChannelLock() {
2        mu := make(chan int, 1)
3        mu <- 0
4
5        x := <- mu
6        x = x * 2
7        mu <- x
8}()

broadcast

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}

limited concurrency

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}