asyncio
是Python 3.4版本引入的標準庫,直接內置了對異步IO的支持。asyncio
的編程模型就是一個消息循環。咱們從asyncio
模塊中直接獲取一個EventLoop
的引用,而後把須要執行的協程扔到EventLoop
中執行,就實現了異步IO。例如:編程
# -*- coding: utf-8 -*- import threading import asyncio @asyncio.coroutine def hello(): print('Hello world! (%s)' % threading.currentThread()) yield from asyncio.sleep(1) print('Hello again! (%s)' % threading.currentThread()) loop = asyncio.get_event_loop() tasks = [hello(), hello()] loop.run_until_complete(asyncio.wait(tasks)) loop.close()
運行結果:併發
Hello world! (<_MainThread(MainThread, started 4589409728)>)
Hello world! (<_MainThread(MainThread, started 4589409728)>)
Hello again! (<_MainThread(MainThread, started 4589409728)>)
Hello again! (<_MainThread(MainThread, started 4589409728)>)異步
@asyncio.coroutine
把一個generator標記爲coroutine類型,而後,咱們就把這個coroutine
扔到EventLoop
中執行。async
用asyncio
提供的@asyncio.coroutine
能夠把一個generator標記爲coroutine類型,而後在coroutine內部用yield from
調用另外一個coroutine實現異步操做。oop
hello()
會首先打印出Hello world!
,而後,yield from
語法能夠讓咱們方便地調用另外一個generator
。因爲asyncio.sleep()
也是一個coroutine
,因此線程不會等待asyncio.sleep()
,而是直接中斷並執行下一個消息循環。當asyncio.sleep()
返回時,線程就能夠從yield from
拿到返回值(此處是None
),而後接着執行下一行語句。線程
把asyncio.sleep(1)
當作是一個耗時1秒的IO操做,在此期間,主線程並未等待,而是去執行EventLoop
中其餘能夠執行的coroutine
了,所以能夠實現併發執行。code
爲了簡化並更好地標識異步IO,從Python 3.5開始引入了新的語法async
和await,其中:
協程
把@asyncio.coroutine
替換爲async
;utf-8
把yield from
替換爲await
。 ci
上述例子能夠改爲:
# -*- coding: utf-8 -*- import threading import asyncio async def hello(): print("Hello world!") r = await asyncio.sleep(1) print("Hello again!") loop = asyncio.get_event_loop() tasks = [hello(), hello()] loop.run_until_complete(asyncio.wait(tasks)) loop.close()