⚡ Zig Guide LiveUnofficialbut fully verified
✓ Zig 0.18.0-dev.624+b7f2c6d8fWhat's newOn an older Zig?Blograylib-zig

Concurrency

Concurrency in Zig uses one interface. Anything that can block takes an `std.Io`, so the function that starts the work never decides how the work is scheduled. Only `main` makes that choice. These chapters follow the interface from the first `io.async` call to the point where you choose an implementation. The first topics are futures and groups, how to stop a task that already runs, how to wait for the first task that finishes, and a bounded queue between two tasks. The other topics are the locks under shared state, the atomics that make those locks, and the OS threads to use when the interface is not what you want. The section ends with a full program, not a primitive. Five of the ten chapters run in your browser, on a target with no threads, and this shows that the interface keeps its promise. Read the Io Interface chapter, in the Standard Library section, first.

  1. std.Thread.spawn still exists, but it is not the default now. Structured concurrency uses std.Io, and it compiles for targets that have no threads.
  2. io.async can run your function inline and return a Future that is already complete. Only io.concurrent promises that the caller continues, and io.concurrent can fail with error.ConcurrencyUnavailable.
  3. Cancellation is a request, not a kill. The task gets the request at its next cancellation point. That is the reason why anything that can block takes the Io.
  4. Only main chooses the implementation. Every function below main takes the interface, and never learns if the implementation has threads.
  5. A mutex is not a primitive. std.atomic.Mutex is one compare-and-swap that takes the lock and one ordered store that releases the lock. The type does nothing more.
  6. std.Thread.Mutex, RwLock, Semaphore, Condition, ResetEvent, WaitGroup and Pool do not exist now. Everything that waits moved to std.Io. std.Thread kept spawn and the four calls that are really about an OS thread.
  7. If the output of a concurrent program depends on the order of its tasks, nobody can test the program. Make the result independent of the schedule. Then you can change the concurrency later, and the result stays the same.

10 chapters.

  • Async, Future and Groupasync, Future, and Group, all through the Io interface.
  • CancellationHow to stop a task that runs, and the cancellation points that make it possible.
  • SelectWait for the task that completes first, and cancel the other tasks.
  • QueuesIo.Queue as a bounded channel between tasks, with close and back pressure.
  • Locks and SemaphoresRwLock, Semaphore and Condition, for the cases where a Mutex is not sufficient.
  • AtomicsOne counter, all the ways to add one to it, and the purpose of the ordering argument.
  • ThreadsReal OS threads, and why this page cannot run in your browser.
  • Migrate from `std.Thread`Seven names that Zig removed, where each one went, and why lock can now fail.
  • Choose an IoThreaded, the evented implementations, and how to build an Io yourself.
  • A Batch Job RunnerFour workers, one batch, three kinds of shared state, and a measurement that says one thread did all of the work.