I/O multiplexing lets an operating system monitor multiple I/O resources, queue their events, and report which sockets are ready. The application can wait without busy-waiting, then process several connections through one thread. section 11.4
The basic flow is:
- Register sockets and the read or write events they may produce. section 11.4
- Block in select until at least one registered socket becomes ready, or return immediately when events are already waiting. section 11.4
- Process each ready socket, then return to the event loop so other connections can be handled. section 11.4
- Use platform-specific alternatives such as poll, epoll, kqueue, IOCP, or /dev/poll when appropriate. section 11.4
A single-threaded pizza server
An event-driven server registers its listening socket and client sockets, waits in select, and dispatches ready events to callbacks such as _on_accept, _on_read, and _on_write. Each callback handles one event type before control returns to the loop, allowing multiple clients to be served without one thread per client. section 11.5
# Chapter 11/pizza_reactor.py
class EventLoop:
def __init__(self) -> None:
self.writers = {} #1
self.readers = {} #1
def register_event(self, source: socket, event: Mask,
action: Action) -> None:
key = source.fileno() #2
if event & select.POLLIN: #3
self.readers[key] = (source, event, action) #3
elif event & select.POLLOUT: #4
self.writers[key] = (source, event, action) #4
def unregister_event(self, source: socket) -> None: #5
key = source.fileno()
if self.readers.get(key):
del self.readers[key]
if self.writers.get(key):
del self.writers[key]
def run_forever(self) -> None:
while True: #6
readers, writers, _ = select.select( #6
self.readers, self.writers, []) #6
for reader in readers: #7
source, event, action = self.readers.pop(reader) #7
action(source) #7
for writer in writers: #8
source, event, action = self.writers.pop(writer) #8
action, msg = action #8
action(source, msg) #8
Inspect the event-loop listing to see readers and writers registered by socket descriptor and dispatched through the readiness mechanism. section 11.5
