Notes From Guido van Rossum talk at LinkedIn, Mountain View, 2014-01-23
Only available in Python 3.4 and later, compatible with Python 3.3
There are multiple ways of doing asynchronous I/O (files & network)
- OS threads
- UNIX “selects”
- Windows “ready callback”
Use transports/protocols as the higher level abstraction
Underneath it’s still an event loop
- see PEP-380 yield from
- also see Twisted
- released in Python 3.4 (compatible with 3.3)
- it has been ported to Python 2.6-2.7: see Project Trollius
Components
- Coroutines / Futures / Tasks
- Event loop & loop policy
- Transports & Protocols
Coroutine
import asyncio @coroutine def generator_func( ... ): yield from some_method( ... )
Tulip uses Futures and Tasks:
Future
representing an eventual result
Task
a Future wrapping a coroutine
Code Example
@coroutine def fetch(host, port): r, w = yield from open(host, port) w.write(r'GET /index.html \r\n\r\n') while (yield from r.readline()) pass body = yield from r.read() return body
Yes, but what does that mean?
- Imagine yield from isn’t there
- each function is sequential code
- the ‘yield from‘ are used only on blocking I/O calls
Futures
PEP-3148
import concurrent.futures.Future
example usage for a Future:
f = Future() f.set_result(res) res = f.result() f.done() # are we there yet?
We can set a callback (or several) on a Future:
f.add_done_callback(cb) yield from f
once it’s done() it will call cb
Typically a Future is used with a blocking method call:
res = yield from some_function( ... )
which returns a future and blocks
Task
A coroutine wrapped in a Future (a subclass of Future)
r = yield from Task(some_coroutine( ... ))
Use a Task when you want progress even while you’re waiting for something else.
Further Reading
- PEP-3156: http://www.python.org/dev/peps/pep-3156/
- Code: http://code.google.com/p/tulip/
- Python Futures: http://docs.python.org/3.4/library/concurrent.futures.html
- Link to Streaming Video (probably a recorded version will be available there too?)
Leave a comment