liveBook · Manning

Blocking

As explained in Python Concurrency with asyncio

A socket operating mode in which an application waits for an I/O operation to complete before continuing.

Blocking means that execution waits for an operation to finish before continuing. Slow I/O, such as reading from a network or waiting for user input, can leave an application frozen or unresponsive because later work cannot run. section 1.1

Sockets are blocking by default: accept, read, or write can halt the application until data arrives, an error occurs, or a timeout expires. Non-blocking sockets return control immediately and let the operating system report readiness later. section 1.6.1

One client holds up another

A simple echo server accepts a client and then waits in recv for that client’s message. While it waits, a second telnet client cannot be processed. Marking the socket non-blocking prevents the receive operation from stopping the next loop iteration. section 3.2.2

Blocking calls are especially important in asyncio because they block its event-loop thread. Wrapping requests.get or time.sleep in async def does not make them asynchronous: tasks created together still execute serially around the blocking call. Use coroutine-based libraries such as aiohttp, or move unavoidable synchronous work into a thread pool. section 2.7.2 section 2.10

Figure 1.8 Making a non-blocking I/O request returns immediately and tells the O/S to watch sockets for data. This allows execute_other_code() to run right away instead of waiting for the I/O requests to finish. Later, we can be alerted when I/O is complete and process the response.
01-08

The figure contrasts an I/O request that blocks with one that returns immediately while the operating system watches for socket readiness. section 1.6.1

Existing synchronous libraries remain usable when their blocking operations run in threads. In asynchronous web views, sync_to_async provides a similar bridge, but thread-sensitive mode can still block the application’s main worker when shared state requires one thread. section 7.0 section 9.4.1

How Python Concurrency with asyncio covers it

How deep it goes
Explains blocking from application behavior through socket calls and event-loop effects, then defers implementation to non-blocking libraries and threads.
Examples
Demonstrates frozen applications, a two-client echo server, requests.get, time.sleep, aiohttp, and sync_to_async.
What it assumes
Assumes basic sequential execution and I/O, while introducing concurrency, sockets, coroutines, and event-loop behavior progressively.
What you can do after
Diagnose blocking calls and choose non-blocking libraries or thread-based bridges for responsive asynchronous applications.
How it connects
Connects blocking with synchronous I/O, concurrency, non-blocking sockets, asyncio, event loops, coroutines, and thread pools.

Also explained in

Compare how 9 books explain blocking →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Python Concurrency with asyncio. The section links point to the parts of the book it draws on.