interrupt-driven I/O
Instead of standing at the kettle staring until it boils, you switch on an electric kettle that whistles when it is done, then go answer emails. The whistle pulls you back exactly when there is something to do, and not a second sooner. Interrupt-driven I/O is the computer using a whistle: the CPU starts a device, then goes off to run other work, and the device raises an interrupt — an electrical signal — the moment it has finished or has data ready.
Concretely, the flow is: the CPU writes a command to the controller to start the operation, then returns to running other processes. The slow device works on its own. When it finishes, the controller asserts an interrupt line. The CPU finishes its current instruction, saves what it was doing, looks up the right handler through the interrupt vector, runs that interrupt service routine to move the data or note the completion, restores its saved state, and resumes whatever it had been doing. Compared with polling, the difference is night and day: the CPU does not waste cycles asking 'ready yet?' — it does real work and is interrupted only when there is genuinely something to handle.
Why it matters: this is the workhorse scheme for most devices that are slow relative to the CPU but still need timely service — keyboards, mice, network cards, disks at moderate rates. It lets one CPU keep many devices and many processes humming at once. Its limit is overhead per interrupt: each one costs a state save, a handler call, and a state restore, so for very high-rate streams (gigabit networking, fast SSDs) a flood of interrupts can itself swamp the CPU — which is why such devices add direct memory access, and sometimes deliberately batch or coalesce interrupts.
You start a disk read and your program is put to sleep. The CPU runs other processes for the next several milliseconds. When the disk has the data, its controller raises an interrupt; the OS wakes your program and hands it the data. No cycles were wasted waiting.
The CPU works on other things and is summoned only when the device is actually done.
Interrupt-driven I/O still has the CPU move each byte in its handler (just only when data is ready). To avoid even that for large blocks, you need direct memory access, which interrupts only once at the very end.