The asyncio module allows for asynchronous input and output, event loops, single threading coronoutines and tasks.
Base Event Loop
In asyncio the event loop is the central execution device.
With it you can:
- Register, execute, and cancel delayed callouts.
- For various kinds of communication create client and server transports
- Launching subprocesses associated with transports
- Delegating function calls to a pool of threads
Coroutines
Coroutines with asyncio may be implemented using the async def statement or by using generators.
Generator-based coroutines should be decorated with @asyncio.coroutine. The decororator enables compatibility with async def coroutines. Generator-based coroutines use the yeild from syntax.
Here is a simple example of an asyncrhonous countdown using a generator-based coroutine:
import asyncio @asyncio.coroutine def my_coroutine(task_name, seconds_to_sleep=3): print('{0} sleeping for: {1} seconds'.format(task_name, seconds_to_sleep)) yield from asyncio.sleep(seconds_to_sleep) print('{0} is finished'.format(task_name)) loop = asyncio.get_event_loop() tasks = [ my_coroutine('task1',4), my_coroutine('task2',3), my_coroutine('task3',2)] loop.run_until_complete(asyncio.wait(tasks)) loop.close()
- A coutroutine can be suspended and then returns the future’s result or rasises an exception which can be propagated. Syntax can be represented as: result yeild from future
- The coroutine expression must call another to another coroutine. result = yield from coroutine waits for another coroutine to produce a result or exception.
- return expression – produces a result to the coroutine that is waiting for the one using yeild from or await
- raise exception – raises an exception from the in the coroutine that is waiting for the on using yeild from or await
Beginner hello world script:
import asyncio async def hello_world(): print("hello world!") loop = asyncio.get_event_loop() #blocking call which returns the hello_world() coroutine is doneloop.run_until_complete(hello_world()) loop.close()
Coroutine displaying the current date/time for 5 seconds:
import asyncio import datetime async def display_date(loop): end_time = loop.time() + 5.0 while True: print(datetime.datetime.now()) if (loop.time() + 1.0) >= end_time: break await asyncio.sleep(1) loop = asyncio.get_event_loop() # Blocking call which returns the display_date() coroutine is done loop.run_until_complete(display_date(loop)) loop.close()
Chained coroutines:
import asyncio async def compute(x,y): print("Compute %s + %s ..." % (x,y)) await asyncio.sleep(1.0) return x + y async def print_sum(x,y): result = await compute(x,y) print("%s + %s = %s" % (x,y,result)) loop = asyncio.get_event_loop() loop.run_until_complete(print_sum(1,2)) loop.close()