When developing a new I/O-bound application from scratch, asyncio may be a natural technology choice. From the beginning, you’ll be able to use non-blocking libraries that work with asyncio, such as asyncpg and aiohttp, as you begin development. However, greenfields (a project lacking constraints imposed by prior work) development is a luxury that many software developers don’t have. A large portion of our work may be managing existing code 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 yet exist. 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 enables 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 we can get the benefits of threading while still using the asyncio APIs, such as gather and wait.