Understanding Concurrency Patterns in Go

Comparing sync and channel approach in goroutines

pancy
Code Zen
3 min readMar 12, 2016

--

Go is an awesome language with great built-in support for concurrency. However, I feel that this topic isn’t very much in the clear, often discussed lightly at the end of the books, and keeping many away from using Go in production.

sync.WaitGroup (low-level style)

sync is a package providing basic synchronization primitives for goroutines. sync.WaitGroup is very popular, since it’s slightly faster than channels and is easy to understand.

Run in the playground.

Channels

Channels are a unique primitive in Go, serving as a fruition of the great doctrine from Go’s authors:

Don’t communicate by sharing memory; share memory by communicating.

If you have programmed anything remotely similar to a queue (i.e. a Python queue), channels are not so different.

Here is the equivalent of the above snippet, rewritten using a channel.

Run in the playground.

This is straightforward and produces similar outcome to the sync.WaitGroup approach. The advantages of using channels are

  • you don’t have to manage the waitgroup with Add() and Done(), removing one more error-prone step to deadlocking.
  • Channel is a better abstraction of synchronizing communication in general (akin event in Javascript) which makes it easy to relate to real-world communications.

Request-Response Mock in Channels

To see how using channels are simpler, check out a simple mock of client-server communication with a channel below

Run in the playground.

This is like how you should be able to send a request and receive a response from a single connection.

Take a look at Code Walk: Share Memory by Communicating if you’re into a few minutes of sitting and reading code.

--

--

pancy
Code Zen

I’m interested in Web3 and machine learning, and helping ambitious people. I like programming in Ocaml and Rust. I angel invest sometimes.