Cooperative Multitasking Timeline
Run the Cooperative Multitasking Timeline MicroSim Fullscreen
Iframe Embed Code
You can add this MicroSim to any web page by adding this to your HTML:
1 2 3 4 | |
About This MicroSim
A swarm robot has three jobs that all feel like they happen "at once": blink a status LED, check for new BLE messages, and read its distance sensor. MicroPython runs one line at a time, so the robot's single thread (one stream of instructions) has to take turns. This MicroSim draws that thread as a timeline so you can see exactly what it is doing at every moment.
- Panel A (Blocking) runs one
while True:loop: blink, check BLE, read the sensor, then calltime.sleep(0.5). The red stripes show the sleep. During a sleep the whole thread is stuck, so nothing else can happen. - Panel B (Cooperative) runs the same three jobs as separate
uasynciotasks. Each task does a tiny bit of work and then pauses atawait asyncio.sleep(...). While one task waits, the event loop (the part ofuasynciothat picks the next task) hands the thread to another task that is ready.
Each job takes the same amount of work time in both panels. The only difference is what the thread does while it waits. Outside events arrive as triangles under each panel: a green triangle is a BLE message, and a red triangle is an obstacle. A green check means the event was handled within 50 ms. A red X shows how many milliseconds late it was.
This MicroSim goes with Chapter 13: Swarm Robotics and Advanced Engineering Patterns, in the section on multithreading and asynchronous programming.
How to Use
- Predict first. Before you press anything, guess: if a BLE message arrives while Panel A is sleeping, how long will it wait?
- Press BLE message or Obstacle. The clock starts, and the event appears at the purple playhead in both panels. Watch how long each panel takes to notice it.
- Press Random events to drop a new event every 0.3 to 1 second. Let it run, then compare the On time, Late, and Thread idle counters.
- Drag Sensor read up to 100 ms. Panel B now gets late events too. The red warning
explains why: a long job with no
awaitstill blocks everyone. - Uncheck Long time.sleep() in Panel A. Panel A now sleeps for only the BLE poll time. Does it catch up with Panel B?
- The code box to the right of each panel highlights the line that is running right now.
In Panel B, the light purple lines are tasks that are paused at
await.
Lesson Plan
Learning Objective
Students will compare (Bloom's Taxonomy: Analyze) a blocking loop built on
time.sleep() with cooperative uasyncio tasks built on await asyncio.sleep(),
explain why the cooperative version lets other tasks run during a pause, and predict
which outside events a blocking program will handle late.
Grade Level
Grades 8–12
Duration
20–25 minutes
Prerequisites
whileloops, functions, andtime.sleep()from Chapter 4: Control Flow, Functions, and Exception Handling- Reading a distance sensor from Chapter 8: Sensors and Data Input
- Checking for BLE messages from Chapter 12: Bluetooth Low Energy Fundamentals
- The
uasyncioexample in the Chapter 13 section "Doing Two Things at Once"
Activities
- Prediction (5 min): Project the sim in its paused state. Ask students to write a prediction: "A BLE message arrives 0.1 s into Panel A's 0.5 s sleep. How many milliseconds late will it be handled?" Collect a few predictions before running it.
- Guided exploration (8 min): Pairs press Random events and run the clock for about 10 seconds, then record the three counters for each panel. Pairs then set Sensor read to 100 ms and record the counters again. They should notice that Panel B's lateness now clusters around 100 ms, which is the length of the un-awaited sensor read.
- Variable isolation (5 min): Pairs uncheck the long-sleep box and vary the Blink period and BLE poll sliders one at a time. Ask them to state which setting controls the worst-case delay in each panel.
- Transfer to hardware (5 min): Students annotate a copy of the chapter's
uasyncioexample and mark every line where the event loop is allowed to switch tasks. They should mark only theawaitlines.
Discussion Questions
- Panel A's thread is idle about 95% of the time, yet it handles most events late. How can a thread be "idle" and still unable to respond?
- Why does Panel B's worst-case delay depend on the longest job that has no
await, rather than on the blink period? - When would a real
_threadsensor loop (from the chapter's multithreading example) be a better choice than auasynciotask?
Assessment
- Formative: During Activity 2, each pair reports the worst-case lateness for both panels and explains the number in one sentence that names the blocking line of code.
- Exit ticket: "A student adds
time.sleep(0.2)inside oneuasynciotask. Predict what happens to BLE messages, and name the one-word fix." (Expected answer: every task stalls for up to 0.2 s; replace it withawait asyncio.sleep(0.2).) - Rubric (4-point): Exemplary — correctly predicts lateness in both panels and
explains it through the blocking line; Proficient — correct prediction with a partial
explanation; Developing — identifies that Panel A is slower but cannot say why;
Beginning — cannot connect
sleep()to missed events.
References
- MicroPython asyncio library documentation —
official reference for
asyncio.run(),create_task(), andasyncio.sleep(). - MicroPython time module documentation —
explains the blocking
time.sleep()and theticks_ms()helpers used for non-blocking timing. - Application of uasyncio to hardware interfaces (Peter Hinch) — a detailed community tutorial on cooperative scheduling in MicroPython.
- Cooperative multitasking (Wikipedia) — background on task switching that happens only at voluntary pause points.
- Event loop (Wikipedia) — the scheduling idea behind the "event loop" lane in Panel B.
- Blocking vs Non-Blocking MicroSim (Learning MicroPython) — the earlier MicroSim this timeline was adapted from.