Midterms 2026See who we think should earn your vote, based on our standardsThe guide →
WRITTEN IN PLAIN AMERICAN ENGLISH.
CLAY TRIBUNE.
Advertisement

Go Concurrency Distilled Makes Goroutines and Channels Interactive With Code Samples

A quick look at Go Concurrency Distilled, a mini-book of interactive examples covering goroutines, channels, and more.

By mitch·4 min read
An illustration showing interconnected gears and glowing threads representing concurrent processes.

Go Concurrency Distilled is a new mini-book that turns Go’s concurrency primitives into a set of interactive examples you can change and run right on the page. The book covers goroutines, channels, select, wait groups, mutexes, semaphores and more, each with live code snippets you can edit and execute. There’s also a PDF version with static examples for printing or reading offline.

The book is described as a quick refresher, not a beginner’s guide. For a deeper dive, the author points readers to Gist of Go: Concurrency, a separate book with practical exercises. The whole project is AI-free, which the author notes explicitly.

Goroutines and Wait Groups

Goroutines are the building blocks of Go concurrency. You start one with the go keyword, and the Go runtime juggles them across operating system threads running on CPU cores. Goroutines are lighter than OS threads, so you can create hundreds or thousands of them without much overhead.

Advertisement

In the example above, two goroutines print “worker 1” and “worker 2” after being launched. A wait group (sync.WaitGroup) tracks their completion. The Add method sets the counter, Done decrements it, and Wait blocks until the counter reaches zero. That keeps the main function from exiting until both workers are finished.

There’s also a WaitGroup.Go method that combines the setup. It increments the counter, runs the function in a goroutine, and decrements the counter when the function ends.

Channels and Channel Directions

Channels let goroutines pass values to each other. A channel is a window where one goroutine throws a value and another catches it. Sending a value through a channel is synchronous: the sending goroutine blocks until the receiving goroutine takes the value.

The book shows a simple example where a goroutine sends “ping” to a channel, and the main function reads it back. The sender blocks on ch <- val, and the receiver blocks on <-ch. Only when the value is received does the sending goroutine continue.

When a channel is no longer needed, Go’s garbage collector frees its resources automatically, whether it’s closed or not. Closing a channel signals to readers that all data has been sent. The reader checks the channel’s status with a second value, called the “comma OK” status.

Here’s how the reader checks:

go
num, ok := <-in
if !ok {
break
}

If ok is false, the channel is closed and the loop stops. If ok is true, the reader gets the next value.

Directional Channels and Buffered Channels

Channels can be bidirectional, send-only, or receive-only. Bidirectional channels are the default. Send-only channels can be declared with chan<- int, and receive-only channels are declared with <-chan int.

You can’t read from a send-only channel or write to a receive-only channel, and you can’t close a receive-only channel. Setting the direction protects against accidental errors.

Buffered channels act like a FIFO queue with a fixed-size buffer. Writing to a buffered channel doesn’t block as long as the buffer has room, and reading doesn’t block as long as the buffer holds values.

The cap and len functions work on buffered channels. cap shows the buffer size, and len shows how many values are currently stored.

Reading from a closed buffered channel works the same way as a regular channel. It returns values from the buffer until the buffer is empty, then returns a zero value with ok set to false.

What This Book Offers

The interactive format is the draw. Instead of reading about concurrency, you can change the code and see the results immediately. That matters for a topic where the timing and ordering of events are often hard to grasp from text alone.

The book is also notable for its absence of AI involvement. In a field where automated tools are everywhere, this is a deliberate choice by the author, and it’s worth noting alongside the technical content.

Topic Key Detail
Goroutines Started with the go keyword; tracked by sync.WaitGroup
Channels Values passed synchronously; closed with close(ch)
Buffered channels FIFO queue with fixed buffer size; use cap and len
Directional channels chan<- for send-only, <-chan for receive-only

The book is a fast read for anyone who already knows Go but wants to tighten their understanding of concurrency. It’s not a substitute for the full Gist of Go: Concurrency, which the author directs beginners toward, but it is a useful companion for the experienced developer looking for a quick refresher.

The interactive examples are the star. Changing a goroutine’s logic and seeing the output shift in seconds is faster than reading through a wall of prose.

The book is a welcome addition to the Go ecosystem. It makes a complex topic accessible through small, runnable examples, and it does so without leaning on automation. That combination — hands-on interaction and careful design — is rare enough to justify a look.

Source material: “Go Concurrency Distilled,” antonz.org.

The Notebook

Get the Notebook.

The day's best stories and every fresh verdict, in plain English, in your inbox by seven. One email a day, no more.

We send one note to confirm. Every issue has a one-click way out.

Advertisement

Leave a Reply

Your email address will not be published. Required fields are marked *

As an Amazon Associate, Clay Tribune earns from qualifying purchases.