March 2017: Concurrency
Meetup #37. Please RSVP at Meetup.
We get started at 6:30 pm.
Sponsors
Venue provided by Startup Edmonton.
Food sponsored by Bellstone Engineering.
Talks
Goroutines
Nathan Youngman gave a gentle introduction to goroutines. He began with hello world and added the go keyword, then used a time.Sleep to show why a program can exit before a goroutine finishes. From there he placed goroutines in context: a process, OS threads, coroutines (cooperative multi-threading managed by a runtime or library), and finally goroutines — which multiplex independently executing functions (coroutines) onto a set of OS threads. He finished with sync.WaitGroup as the way to wait for goroutines to complete.
Key points:
- A goroutine is started with the
gokeyword. - Sleeping is a crude way to let goroutines run before exit.
- Processes, threads, and coroutines provide the background.
- Goroutines multiplex coroutines onto OS threads.
sync.WaitGroupis the idiomatic way to wait for goroutines.
Un-Paralleled Concurrency
Gerrit Renker gave a tour of basic concurrency patterns in Go, built around the proverb "concurrency is not parallelism." He contrasted the classic model of communicating by sharing memory (threads plus mutexes, hard to reason about) with Go's share-memory-by-communicating model based on CSP, and covered channels as FIFO reference types with directional variants. The talk progressed from generators and pipelines through buffered channels, then multiplexing with select. Along the way he demonstrated synchronization signals (empty structs and closed channels), broadcast via closed channels, writer/reader patterns (1:1, 1:n fan-out, n:1 fastest-response-first), the bounded-buffer/counting-semaphore pattern, and cleaning up goroutine leaks. Advanced patterns included futures, a monitor goroutine, and an implementation of the actor model as a goroutine plus a channel mailbox.
Key points:
- Go favours 'share memory by communicating' over shared memory + mutexes.
- Channels are FIFO and can be send-only or receive-only.
- Unbuffered channels synchronize sender and receiver.
- Closing a channel broadcasts a signal to all receivers.
- Buffered channels enable bounded buffers and counting semaphores.
selecthandles timeouts, heartbeats, and message loops.- Advanced patterns: futures, monitor goroutines, and the actor model.
Gotrace
Concurrency tracer and visualizer (source) demonstration by Matthias Stone
The atomic package
Lukasz Rozycki gave an overview of the sync/atomic package. He started with a bank-withdrawal example to show how interleaved statements race: two goroutines both read a balance of 150, both pass the >= amount check, and the balance ends up wrong — a data race the detector will catch. The only operations Go guarantees to be atomic live in sync/atomic, and he walked through its families: AddT (atomic *addr += delta), LoadT/StoreT (to avoid torn reads and writes), SwapT, and CompareAndSwapT (the basis for lock-free loops). He used an HTTP request counter to demonstrate each, then covered atomic.Value, which atomically loads and stores a consistently typed value, with a config-reload example and a read-mostly map updated by copy-on-write.
Key points:
- Plain reads/modifies/writes can interleave into data races.
- Only
sync/atomicoperations are guaranteed atomic. AddTatomically adds and returns the new value.LoadT/StoreTprevent torn reads and writes.SwapTreturns the old value while storing a new one.CompareAndSwapTenables lock-free compare-and-swap loops.atomic.Valuestores a typed value safely, ideal for config reloads.
News
- Women Who Go to GopherCon fundraiser
- WWG Gophercon Scholarship
Events
- Monthly Hack Day - April 1
- GopherCon July 12-15
- Edmonton Go Meetup - April