blob: 00ac48eda57da05cc0a4ef02c8c87afacfeebc3d [file] [log] [blame] [view]
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11001# Use a sync.Mutex or a channel?
2
3One of Go's mottos is _"Share memory by communicating, don't communicate by sharing memory."_
4
5That said, Go does provide traditional locking mechanisms in the <a href='http://golang.org/pkg/sync/'>sync package</a>. Most locking issues can be solved using either channels or traditional locks.
6
7So which should you use?
8
9Use whichever is most expressive and/or most simple.
10
11A common Go newbie mistake is to over-use channels and goroutines just because it's possible, and/or because it's fun. Don't be afraid to use a <a href='http://golang.org/pkg/sync/#Mutex'><code>sync.Mutex</code></a> if that fits your problem best. Go is pragmatic in letting you use the tools that solve your problem best and not forcing you into one style of code.
12
13As a general guide, though:
14
Rick Beton901b5a62015-03-19 14:52:22 +000015| **Channel** | **Mutex** |
16|:------------|:----------|
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110017| passing ownership of data,<br />distributing units of work,<br /> communicating async results | caches,<br />state |
18
19If you ever find your sync.Mutex locking rules are getting too complex, ask yourself whether using channel(s) might be simpler.
20
Rick Betond59028d2015-03-19 15:50:34 +000021### Wait Group
Rick Beton901b5a62015-03-19 14:52:22 +000022
Rick Betond59028d2015-03-19 15:50:34 +000023Another important synchronisation primitive is sync.WaitGroup. These allow co-operating goroutines to collectively wait for a threshold event before proceeding independently again. This is useful typically in two cases.
Rick Beton901b5a62015-03-19 14:52:22 +000024
Rick Betonb538d912015-03-19 14:55:13 +000025Firstly, when 'cleaning up', a sync.WaitGroup can be used to ensure that all goroutines - including the main one - wait before all terminating cleanly.
26
27The second more general case is of a cyclic algorithm that involves a set of goroutines that all work independently for a while, then all wait on a barrier, before proceeding independently again. This pattern might be repeated many times. Data might be exchanged at the barrier event. This strategy is the basis of [Bulk Synchronous Parallelism](https://en.wikipedia.org/wiki/Bulk_synchronous_parallel) (BSP).
Rick Beton901b5a62015-03-19 14:52:22 +000028
Rick Betond59028d2015-03-19 15:50:34 +000029Channel communication, mutexes and wait-groups are complementary and can be combined.
30
31### More Info
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110032
33 * Channels in Effective Go: http://golang.org/doc/effective_go.html#channels
Rick Beton901b5a62015-03-19 14:52:22 +000034 * The sync package: http://golang.org/pkg/sync/