Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Threads

j3.thread gives you threads on Linux: spawn/join, a Pool of workers, Queue<T>, Mutex, and Cond.

The one rule

Hand work over; don’t share it. Give a worker a struct that only it writes, wait for its result, then read it. The compiler does not check for data races, so this rule is the whole safety net.

Picking a tool

You want to…Use
Run one thing in the backgroundspawn(&t, name, f, arg), later join(&t)
Run many jobs on a few workersPool.create(&arena, workers, queueCap), then submit / trySubmit
Do the same work over 0..npool.parallelForEach(n, fn(lo, hi) { .. }) (a closure; it waits for every range, which is why a closure is safe here). Lower level: pool.parallelFor(n, f, ctx)
Get results back to the frame loopA Queue<T>: workers push, the main thread tryPops
Share a counter or cancel flag@atomicAdd / @atomicLoad / @atomicStore on an int, i32, u32, u64, bool or ptr (@atomicAdd only on the integers), with an optional order (acquire, release, relaxed, …)
One value per thread#[singleton] + #[thread] on a let

A thread’s entry point is a plain fn(ptr): its state arrives as one pointer to a struct the spawner owns.

The frame thread must never block

Feed a pool with trySubmit and drain results with tryPop, so a slow job never stalls a frame. Stamp each job with a version and drop results that come back stale.

Main-thread only

The window, OpenGL, SDL, audio, and every j3.game, j3.gfx, j3.scene3d, j3.ui, and j3.app value belong to the main thread. Each thread needs its own Arena.

j3c doc recipes threads prints a complete program; j3c doc threads has the full guide.