Source: Operating Systems: Three Easy Pieces (OSTEP) — Chapter 33, Arpaci-Dusseau & Arpaci-Dusseau
Event-based Concurrency (Advanced)
Threads are not the only way to build concurrent apps. GUIs [O96], some internet servers [PDZ99], and frameworks like node.js [N13] often use event-based concurrency — roots in classic C/UNIX select/poll servers.
Crux: how to build concurrent servers without threads, keep control of scheduling, and dodge many threading bugs?
The event loop
while (1) {
events = getEvents();
for (e in events)
processEvent(e); // one handler at a time
}
Handling an event is the only activity — so choosing which event next = scheduling. That explicit control is a main advantage.
select() / poll()
Ask the OS which FDs are ready to read/write (or have errors). Typical loop: FD_ZERO → FD_SET interested sockets → select → FD_ISSET and processFD.
timeout = NULL— block until readytimeout = 0— poll and return immediately
Rank the sequence
1 / 1Order the steps of one pass through a select()-based event loop.
OrderDrag the handle to rearrange — top should be first.
- 1processFD on each ready descriptor
- 2FD_SET the interested sockets
- 3FD_ZERO to clear the descriptor set
- 4Call select() to find ready descriptors
Drag items into the correct order (or use ↑↓), then check.
Any blocking call stalls the entire server. Non-blocking / async I/O is mandatory.
Why simpler? No locks (on one CPU)
One handler at a time, single-threaded → no other thread interrupts → no locks for shared state between handlers. Concurrency bugs from Ch. 32 largely vanish — until you go multicore.
The problem: blocking system calls
A file-serving request needs open/read. Threads: one thread sleeps on I/O; others run. Events: the only loop blocks → idle waste.
Solution: asynchronous I/O
Fill an aiocb (fd, offset, buf, nbytes), call aio_read — returns immediately. Poll completion with aio_error (or get a signal when done). Systems without good AIO often use a hybrid: events for network + thread pool for disk [PDZ99].
Rank the sequence
1 / 1Order the steps an event handler takes to issue and complete an asynchronous disk read.
OrderDrag the handle to rearrange — top should be first.
- 1Fill an aiocb with fd, offset, buffer, and nbytes
- 2aio_read returns immediately, handler moves on
- 3Call aio_read with the aiocb
- 4Poll aio_error (or receive a completion signal)
Drag items into the correct order (or use ↑↓), then check.
Continuations (manual stack management)
Threads keep sd on the stack across read(fd) then write(sd,…). Events must package state when issuing async I/O — a continuation [A+02,FHK84]: e.g. hash table fd → {sd}; on completion, look up and finish the write.
What is still hard
| Issue | Why it hurts |
|---|---|
| Multicore | Parallel handlers → locks return |
| Paging | Implicit page-fault blocking stalls the loop |
| API drift | A routine becoming blocking forces handler rewrites |
| Split I/O APIs | Often select for net + AIO for disk — not one uniform wait |
Interactive
Try: event loop · select · don’t block · async I/O · continuations.
Check your understanding
Event-based concurrency
1 / 6In a single-threaded event loop, deciding which event to handle next is equivalent to…
Pick an answer to see if you are right.
Coding challenges
Homework lab: event server sketch
There is no dedicated OSTEP code repo for Ch. 33 — build the homework yourself (TCP + select + file serving + optional AIO/signals).
Homework: event-based server
0/6 startedSummary
| Piece | Role |
|---|---|
| Event loop | Wait → handle one-at-a-time (= schedule) |
| select/poll | Which FDs are ready? |
| No blocking | Or the whole server stalls |
| AIO / hybrid | Overlap disk without a sleeping thread |
| Continuations | Manual stack across async steps |
Threads and events both persist — pick based on control, complexity, and platform I/O support [A+02, PDZ99, WCB01, vB+03].
Previous: Common Concurrency Problems
Next: I/O Devices — buses, interrupts, DMA, drivers.
Further Reading
- Remzi & Andrea Arpaci-Dusseau — Operating Systems: Three Easy Pieces Ch. 33
- OSTEP threads-events PDF
- Ousterhout [O96]; Pai et al. Flash [PDZ99]; Welsh et al. SEDA [WCB01]; Adya et al. [A+02]; node.js [N13]; Stevens & Rago [SR05]