Theme Catppuccin
Make yourself at homeCatppuccin

A softer light for long learning sessions.

Appearance

Loading your preference…

Dark palette

Choose a dark palette to try it.

Light uses Latte. Your choices stay in this browser.

A finite number of workers

SKETCHBOOK / 03 The Living Gallery · 2-week chapter

Page 1 of 5: A batch is a scheduling policy

Workers / bounded work

A batch is a scheduling policy

The companion accepts one owned batch and creates a bounded number of C++20 jthreads, available in this C++23 baseline. Compared with a raw std::thread that requires every path to arrange join or detach, jthread attaches cooperative stop and join to its scoped owner. Workers claim indices under a mutex and compute outside that lock. A lock_guard releases its mutex on every ordinary scope exit, including exception unwinding; a unique_lock is used for waits because the wait must unlock and reacquire it. Results have fixed submission-order slots, so completion order does not grow an unbounded result queue.

This is not a general streaming executor. Its run_batch call waits until all workers join, and it does not claim UI responsiveness or asynchronous I/O. Internal parallel work and a nonblocking public interface are different decisions.

Next compare run_batch with AssetPipeline: the latter keeps a bounded set of workers alive, admits image descriptors, and exposes try_take for a caller that must continue handling events. Its short mutex acquisitions can contend, so it is not a lock-free algorithm. The following checkpoints give submission, retained results, shutdown, and publication concrete implementations.

TRY IT IN YOUR STUDIO

Trace two workers claiming four jobs. Mark which state needs the mutex and which data each worker owns or reads independently.

From the page to your own work

Your studio assignment.

Adapt the bounded CPU batch to one owned gallery preparation task.

A finish line you can see

A bounded worker experiment with cancellation ordering, failure outcomes, and a shutdown diagram.

  1. Keep the public blocking/nonblocking contract explicit.
  2. Test cancellation before any payload access.
  3. Join before freeing jobs, gates, or result state.
  4. State what cancellation cannot interrupt.
Keep the evidence in your weekly notebook ↗
Explain it like an engineer

Try answering aloud before opening the review notes. Use your own implementation as evidence.

Why can replacing explicit join with vector.clear change a successful render?
  • Destroying joinable jthreads requests stop before joining.
  • That may cancel still-valid work.
  • Choose normal completion separately from cancellation shutdown.

These prompts support practice; they are not an automatic assessment of your work.

A small creative variation ↗

Compare one and two workers on the same accepted batch, checking identical result slots before measuring time.

Optional. Save it for later if this chapter already feels full.

Coming back after a break? ↩

Run the gated cancellation test and draw its five synchronization events.

Books & principles behind this study +

Original Parallax explanations and assignments, with these works for further reading.

YOUR MARGIN NOTES

Leave yourself a good question.

What changed your mind? What would you try next?

Notes are private to this browser and saved as you write.

A CHECKPOINT, NOT A SCORE

Can you explain the idea and try the exercise yourself?

Completion records your own assessment. It does not compile or test your C++.
Companion source 14 files