Rethinking Parallelism in Go, Simplicity Goes Far

<p>Go, designed by Google, was envisioned as a language that takes advantage of modern computers (and cluster of computers) to run parallel and async code faster, and with simple semantics. However, much of the original ideas and patterns have evolved, simplified, and improved.</p> <p>In&nbsp;<em>Basic Parallel Computing in Go</em>&nbsp;and&nbsp;<em>More on Go Channels, Parallelism and Concurrency&nbsp;</em>we explored some basic concepts about concurrency and parallelism in Go. However, this time we will look at more advanced, but simpler to write performant Go code.</p> <h1>Wait Group</h1> <p>A wait group is an async concept that allows us to wait for certain conditions to happen often used as a Barrier type of synchronization. Barriers allow us to synchronize multiple concurrent operations at certain points which is a powerful thing. Let&rsquo;s look at some code.</p> <p>Suppose we want to download a certain amount of URLs at the same time and do something with them after all have been downloaded. The following function&nbsp;<code>content</code>&nbsp;is the one that downloads the content of the URL and returns it, an error is returned if something fails.&nbsp;<em>The implementation has been omitted</em>.</p> <p>In the code above, we start a goroutine, basically a parallel task that will download a single URL. The result of each operation, regardless of being an error or the actual content is then saved in&nbsp;<code>results</code>.</p> <p>Every time we start a task, we increment the&nbsp;<code>wait group</code>&nbsp;and every time a task ends it decreases the&nbsp;<code>wait group</code>. At the same time,&nbsp;<code>wg.Wait()</code>&nbsp;blocks until all the&nbsp;<code>wait group is 0</code>&nbsp;which is the same as all tasks are done. Effectively,&nbsp;<code>wg.Wait()</code>&nbsp;acts as a barrier for all tasks to sync at that point.</p> <p>This is easier than having channels (as in the previous posts) then sending signals in those channels, and synchronizing over them.&nbsp;<code>WaitGroup</code>&nbsp;enables simplicity without the need of channels or other primitives.</p> <p>One caveat is that&nbsp;<code>WaitGroup</code>&nbsp;should not be copied, so if you need to store it somewhere, it has to be using a pointer to it. However, think twice before doing that.</p> <p><a href="https://blog.stackademic.com/rethinking-parallelism-in-go-simplicity-goes-far-255218a00197">Read More</a></p>