OS//concurrency//asynchronous programming

Asynchronous programming is a style of concurrent programming in which a task that has to wait (for the network, a disk, a database, a model API) hands control back instead of blocking, so one thread can keep thousands of waits in flight and resume each when its answer arrives. It is how a single server process holds ten thousand open connections, and how an agent fires twenty web requests and handles them as they return.


Asynchronous programming is a style of concurrent programming in which a task that has to wait (for the network, a disk, a database, a model API) hands control back instead of blocking, so one thread can keep thousands of waits in flight and resume each when its answer arrives. It is how a single server process holds ten thousand open connections, and how an agent fires twenty web requests and handles them as they return.

The usual mechanics are an event loop plus syntax that makes the code read top to bottom. A function marked async runs until it reaches an await on something slow; at that point it is parked and the loop runs another ready task. In Python:

Copy

results = await asyncio.gather(*(fetch(url) for url in urls))

launches every fetch at once and waits for all of them. If each takes a second, a hundred take about a second in total, because the time was spent waiting, never computing.

Asynchrony buys concurrency, never parallelism.

It overlaps waits on one core; it does not run two computations at the same instant, so it pays off exactly as far as the work is I/O-bound.

One blocking call ruins it. A task that computes for two seconds, or calls a library that blocks, freezes every other task on the loop for those two seconds. CPU-heavy work goes to separate processes or threads, where real parallelism lives (and, in Python, past the GIL).

Async is cheap where threads are not. A parked task costs a few kilobytes; a thread costs a stack of a megabyte or so and a kernel scheduling slot, which is why ten thousand threads hurt and ten thousand tasks do not.

Errors and timeouts become explicit design. A request that never answers blocks nothing, but it also never finishes unless a timeout says so; an agent that gathers tool calls needs a budget per call and a policy for partial results.

The loop that schedules the tasks is described in event loop; why waiting dominates so many workloads is in I/O-bound.