liveBook · Manning

Concurrency

As explained in Python Concurrency with asyncio

A way of structuring work so that multiple tasks make progress during overlapping periods, including by switching between them while each is incomplete.

Concurrency structures work so multiple tasks make progress during overlapping periods. Tasks may alternate while incomplete, allowing an application to do useful work while another task waits for input or output. section 1.1 section 1.3.1

Concurrency is not the same as parallelism. A concurrent system can switch between tasks on one CPU core; a parallel system executes multiple tasks simultaneously, requiring multiple cores or execution units. Parallelism implies concurrency, but concurrency does not imply parallelism. section 1.3.2 section 1.3.3

Use the workload and waiting behavior to choose a concurrency approach:

  • Handle I/O-bound work, such as web requests, database queries, file access, or microservice calls, by overlapping waits instead of performing operations sequentially. section 1.0 section 1.2
  • Use cooperative multitasking when tasks can explicitly pause at long-running operations; other tasks run until the waiting operation completes. section 1.3.5
  • Use threads for concurrent I/O when appropriate, but do not expect ordinary Python threads to execute CPU-bound Python code in parallel because of the GIL. section 1.5.1
  • Use processes for CPU-bound work that can be divided into independent pieces; process pools can run those pieces concurrently and in parallel. section 1.5.2 section 6.7

asyncio achieves single-threaded concurrency with coroutines, non-blocking sockets, and an event loop. A coroutine pauses at await while the operating system tracks socket activity; the event loop then runs other ready work and resumes the paused task when data arrives. section 1.5.2 section 1.6.1

Running several waits together

Creating three asyncio tasks for three-second delays schedules them together. Awaiting them afterward completes in about three seconds rather than more than nine seconds sequentially, while other code can run during the waits. section 2.3.2

Figure 1.1 With concurrency, we have multiple tasks happening at the same time, but only one we’re actively doing at a given point in time. With parallelism, we have multiple tasks happening and are actively doing more than one simultaneously.
01-01

Compare concurrency as switching among overlapping tasks with parallelism as actively executing multiple tasks simultaneously. section 1.3.2

How Python Concurrency with asyncio covers it

How deep it goes
Explains task switching, parallelism, multitasking, GIL effects, sockets, event loops, coroutines, and task scheduling.
Examples
Uses cake baking, web-page downloads, status-code requests, delayed coroutines, echo servers, database queries, and microservice calls.
What it assumes
Assumes basic Python and application programming while teaching concurrency, parallelism, multitasking, sockets, coroutines, and the GIL from fundamentals.
What you can do after
Build it from scratch by choosing threads, processes, or asyncio tasks for I/O-bound and CPU-bound workloads.
How it connects
Connects concurrency with parallelism, multitasking, I/O-bound work, CPU-bound work, threads, processes, coroutines, and event loops.

Also explained in

Compare how 23 books explain concurrency →

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.