Asynchronous Programming with Python Write, Test, and Debug Robust Asynchronous Code

  • Coen de Groot

Your browser needs to be JavaScript capable to view this video

Try reloading this page, or reviewing your browser settings

You're watching a preview of subscription content. Log in to check access

In this course, we will look at using asynchronous programming in Python: the options, pitfalls, and best practices. We start with multi-threading, which is particularly useful when there is a lot of waiting, e.g. for HTTP requests or disk access. With multi-threading, you can start many requests in quick succession and then wait for all of them to complete at once. Next, the course will show you how to write your code in a thread-safe manner, and how to use it risk-free. Further, it covers Python’s global interpreter lock, which prevents a lot of serious problems in Python but also stops you from running threads in parallel.

Going forward we discover how you can use Python’s multiprocessing library to run functions in parallel. Threads and processes often need to share or exchange data. In asynchronous code just passing Python objects is usually not the safest way to do this. This course looks at the main ways to do this correctly in Python, such as queues and events. Finally, the course moves on to the concurrent.future library which contains higher-level abstractions, including thread and processing pools and an asynchronous map function.

The course finishes with advice on how to write robust asynchronous code, and how to test and debug it.

What You Will Learn

  • Take advantage of multi threading (concurrency) using the threading module

  • Implement multi processing (parallelism) using the multiprocessing module

  • Understand inter-process communication and data sharing using locks, queues, semaphores, barriers, events, and timers

  • Test and debug asynchronous Python code

  • Understand thread and process pools using concurrent.futures

Who This Video Is For

Intermediate to experienced Python programmers who want to speed up existing Python code by using multi processing and multi threading.

In this video course, we will look at using asynchronous programming in Python: the options, pitfalls, and best practices. We start with multi-threading, which is particularly useful when there is a lot of waiting, e.g. for HTTP requests or disk access.

About The Author

Coen de Groot

Coen de Groot is a freelance Python developer and trainer. He has been passionate about computers and programming since the late ‘70s when he built his first ‘computer’.

After studying computer science at Leiden University in the Netherlands, Coen worked as a software engineer for several companies, from a large oil company to small start-ups, working in software support, delivering training, and leading software teams.

For the past ten years Coen has been programming predominantly in Python, with hints of SQL, JavaScript, and others. He still enjoys learning more Python and passing on that knowledge to others face to face, in writing, or on video.


Supporting material

View source code at GitHub.

About this video

Coen de Groot
Online ISBN
Total duration
1 hr 26 min
Copyright information
© Coen de Groot 2020

Related content

Video Transcript


Welcome to this video on asynchronous programming in Python with threads and processes. Sometimes you want your Python program to fully utilize the power of your computer to do something useful, even whilst waiting for a websites to respond and use all cores of your CPU. We will look at multi-threading and multiprocessing and which to use when.

Throughout this video, you will see a lot of sample Python scripts, starting with examples of multi-threading. You may see some subtle errors when using threads. Locks can help but have their own problems.

The syntax for multiprocessing is very similar to multitasking, even though it works completely differently under the hood. We will look at using cues, semaphores, events, and barriers to let threads and processes work as a team. Once we understand the basics, we can use polls and futures to simplify much of our asynchronous code.

Asynchronous code is often difficult to get right. We will cover how to write a robust and tested code and how to debug it if it doesn’t work. Doing a calculation in Python is fast– maybe not as fast as in a compiled language like C, but it can still do millions of calculations per second. A web request, such as getting the Python website home page, is much slower– hundreds of thousands of calculations in the time of one web request.

In general calculations and other CPU-based operations are very fast, whilst input or output is very slow. Simply put, the closer something happens to the CPU, the faster. A website request has to travel thousands of miles and then wait its turn for the server to process it and return a response.

Reading from or writing to a hard disk means waiting for the platter to spin into position. Even at 7,200 runs per minute, this still takes some time. Solid-state disks don’t have any mechanical components and are much faster, but they are still a relatively long way away from the CPU. A database query takes some processing, but also file access. And finally, writing something to the screen takes a lot of steps just to work out which pixels to put where.

When handling I/O, your CPU typically spends most of its time waiting for the outside world. A program is CPU-bound when it is using the full capacity of the CPU, when having a faster CPU will speed it up– for instance, machine learning, or other heavy calculations. Python can only run in one core at a time. However, using multiprocessing, we can start multiple copies of Python and spread the work over multiple cores.

A program is a I/O bound when it spends a lot of its time waiting for input or output to be handled. The CPU, even the one core used to run Python, is seriously underused. Whilst waiting for a website request, Python could be doing something else, such as requesting another web page. We can do that by creating multiple threads. When a thread is waiting for some I/O, it automatically get suspended so another thread can run.

A brief word about the demonstrations in this video. With asynchronous processing, the order in which things happen often varies. If you run the code yourself, you may get slightly different results from what you’ll see in the video.

When multiple threads or processes print at almost the same time, the output can get mixed up. Typically, it will be broken up between the visible text and the end-of-line character. What you may see is two numbers squashed together on the same line, followed by a blank line.

My name is Coen de Groot. I am a freelance Python developer and trainer with many years’ experience. I help my clients make better use of the data, give their customers a better experience, write better Python code, and more.