Benefits of asyncio
On 06/02/14 20:40, Aseem Bansal wrote:
> I read in these groups that asyncio is a great addition to Python 3. I have looked around and saw the related PEP which is quite big BTW but couldn't find a simple explanation for why this is such a great addition. Any simple example where it can be used?
AFAIR, Guido's US Pycon 2013 keynote is where he introduced asyncio (or
tulip, which is the "internal codename" of the project) so you can watch
it to get a good idea about his motivations.
So what is Asyncio? In a nutshell, Asyncio is Python's standard event
loop. Next time you're going to build an async framework, you should
build on it instead of reimplementing it using system calls available on
the platform(s) that you're targeting, like select() or epoll().
It's great because 1) Creating an abstraction over Windows and Unix way
of event-driven programming is not trivial, 2) It makes use of "yield
from", a feature available in Python 3.3 and up. Using "yield from" is
arguably the cleanest way of doing async as it makes async code look
like blocking code which seemingly makes it easier to reason about the
flow of your logic.
The idea is very similar to twisted's @inlineCallbacks, if you're
familiar with it.
If doing lower level programming with Python is not your cup of tea, you
don't really care about asyncio. You should instead wait until your
favourite async framework switches to it.
> It can be used to have a queue of tasks? Like threads? Maybe light weight threads? Those were my thoughts but the library reference clearly stated that this is single-threaded. So there should be some waiting time in between the tasks. Then what is good?
You can use it to implement a queue of (mostly i/o bound) tasks. You are
not supposed to use it in cases where you'd use threads or lightweight
threads (or green threads, as in gevent or stackless).
Gevent is also technically async but gevent and asyncio differ in a very
subtle way: Gevent does cooperative multitasking whereas Asyncio (and
twisted) does event driven programming.
The difference is that with asyncio, you know exactly when you're
switching to another task -- only when you use "yield from". This is not
always explicit with gevent, as a function that you're calling can
switch to another task without letting your code know.
So with gevent, you still need to take the usual precautions of
multithreaded programming. Gevent actually simulates threads by doing
task switching (or thread scheduling, if you will) in userspace. Here's
its secret sauce:
There's some scary platform-dependent assembly code in there! I'd think
twice before seriously relying on it.
Event driven programming does not need such dark magic. You also don't
need to be so careful in a purely event-driven setting as you know that
at any point in time only one task context can be active. It's like you
have an implicit, zero-overhead LOCK ALL for all nonlocal state.
Of course the tradeoff is that you should carefully avoid blocking the
event loop. It's not that hard once you get the hang of it :)
So, I hope this answers your questions. Let me know if I missed something.