[Python-Dev] A more flexible task creation
Steve Dower
steve.dower at python.org
Thu Jun 14 16:03:12 EDT 2018
On 14Jun2018 1214, Chris Barker via Python-Dev wrote:
> Excuse my ignorance (or maybe it's a vocabulary thing), but I'm trying
> to understand the problem here.
>
> But if I have this right:
>
> I've been using asyncio a lot lately and have encountered this
> problem several times. Imagine you want to do a lot of queries
> against a database, spawning 10000 tasks in parallel will probably
> cause a lot of them to fail.
>
>
> async is not parallel -- all the tasks will be run in the same thread
> (Unless you explicitly spawn another thread), and only one task is
> running at once, and the task switching happens when the task
> specifically releases itself.
If the task isn't actually doing the work, but merely waiting for it to
finish, then you can end up overloading the thing that *is* doing the
task (e.g. the network interface, database server, other thread/process,
file system, etc.).
Single-threaded async is actually all about *waiting* - it provides a
convenient model to do other tasks while you are waiting for the first
(as well as a convenient model to indicate what should be done after it
completes - there are two conveniences here).
If the underlying thing you're doing *can* run in parallel, but becomes
less efficient the more times you do it (for example, most file system
operations fall into this category), you will want to limit how many
tasks you *start*, not just how many you are waiting for. I often use
semaphores for this when I need it, and it looks like
asyncio.Semaphore() is sufficient for this:
import asyncio
task_limiter = asyncio.Semaphore(4)
async def my_task():
await task_limiter.acquire()
try:
await do_db_request()
finally:
task_limiter.release()
Cheers,
Steve
More information about the Python-Dev
mailing list