PythiloLesson 12 of 12 · progress kept in this browser

Blocking code and to_thread

The event loop runs on one thread. A coroutine that calls a blocking function, such as time.sleep, a big file read or a library without async support, freezes every other task until that function returns.

asyncio.to_thread(func, *args) runs the function in a worker thread and gives you something to await. Meanwhile the loop keeps running other tasks.

import asyncio
import time

def read_sensor(n):
    time.sleep(0.01)  # blocking
    return n * 10

async def main():
    values = await asyncio.gather(
        asyncio.to_thread(read_sensor, 1),
        asyncio.to_thread(read_sensor, 2),
    )
    print(values)  # [10, 20]

asyncio.run(main())
Your task

Write async def read_all(paths, read), where read(path) is an ordinary blocking function. Run every read at the same time in worker threads, keep the event loop free while they run, and return the results as a list in the order of paths.

This lesson uses threads, which Python in this browser does not include. Read it here, and run and check it in the Pythilo app on iPhone or iPad.

All lessons