Skip to content

Instantly share code, notes, and snippets.

@twotwotwo
Last active February 27, 2022 14:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save twotwotwo/fe5c5020a2bb5f7f0ce3 to your computer and use it in GitHub Desktop.
Save twotwotwo/fe5c5020a2bb5f7f0ce3 to your computer and use it in GitHub Desktop.
Concurrency links

Spec sections on channels (https://golang.org/ref/spec#Channel_types), send (https://golang.org/ref/spec#Send_statements), receive (https://golang.org/ref/spec#Receive_operator), select (https://golang.org/ref/spec#Select_statements), close (https://golang.org/ref/spec#Close). The memory model is described at https://golang.org/ref/mem.

Running a concurrent test under the race detector is a useful check. Helps to get a little familiarity with the sync package: https://godoc.org/sync. Introductory stuff mostly emphasizes channels, because that's what's specific to Go, but when your goal isn't communication you should be aware of, e.g. sync.WaitGroup to wait for workers to finish, sync.Mutex or sync.RWLock when you're really just sharing data, sync.Once during init, sync/atomic in the somewhat rarer cases you have global state you can update atomically.

For performance, if you have tiny tasks (where microseconds of overhead per task matters), using buffers or batching them can help; it's rarely an issue when network or DB operations are involved, but can be on small pure-computation tasks. I ran into this in some parallel sorting code (and dealt by only sending sorts of 128+ items to other sort workers). Standard library source also has some concurrency management--it's usually readable code, though sometimes you have to understand what it's doing to understand what the concurrency primitives are there for.

I hate to say this but in learning this stuff there's often a certain amount of trial and error, in getting to elegance if not to correctness; I think my first largish Go program accidentally implemented a lock using a buffered channel. It may help to open a text file somewhere to sketch out your goroutines, channels, etc. (separated from all the other details of your app), why you need each, and see if you can remove anything or change something to a better-fitting primitive.

Couple third-party things I haven't actually looked at:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment