7 Handling blocking work with threads
This chapter covers
- The multithreading library
- Creating thread pools to handle blocking I/O
- Using async and await to manage threads
- Handling blocking I/O libraries with thread pools
- Shared data and locking with threads
- Handling CPU bound work in threads
When developing a new I/O bound application from scratch, asyncio may be a natural technology choice. Starting out, you’ll be able to use non-blocking libraries that work with asyncio such as asyncpg and aiohttp as you begin development. However, greenfields development is a luxury that many developers don’t have. A large portion of our work may be managing code written a while ago using blocking I/O libraries such as requests for HTTP requests, psycopg for Postgres databases or any number of blocking libraries. We may also be in a situation where an asyncio-friendly library does not exist yet. Is there a way to get the performance gains of concurrency while still using asyncio APIs in these cases?
Multithreading is the solution to this question. Since blocking I/O releases the global interpreter lock, this opens up the possibility to run I/O concurrently in separate threads. Much like the multiprocessing library, asyncio exposes a way for us to utilize pools of threads so that we can get the benefits of threading while still using the asyncio APIs such as gather and wait.