文章目錄
爲什麼使用協程編程?
- 順便學個單詞:
async
意思是’異步’, python中的關鍵字:asyncio
即是異步IO,也即協程 - 協程最大的優勢就是極高的執行效率。因爲子程序切換不是線程切換,而是由程序自身控制,因此,沒有線程切換的開銷,和多線程比,線程數量越多,協程的性能優勢就越明顯。
- 第二大優勢就是不需要多線程的鎖機制,因爲只有一個線程,也不存在同時寫變量衝突,在協程中控制共享資源不加鎖,只需要判斷狀態就好了,所以執行效率比多線程高很多。
- 多進程+協程,既充分利用多核,又充分發揮協程的高效率,可獲得極高的性能。
- Python對協程的支持是通過generator實現的
- 適用場景: IO密集型任務, 如網絡連接, 磁盤讀寫等
關鍵字解釋
-
event_loop 事件循環:程序開啓一個無限循環,把一些函數註冊到事件循環上,當滿足事件發生的時候,調用相應的協程函數
-
coroutine 協程:協程對象,指一個使用async關鍵字定義的函數,它的調用不會立即執行函數,而是會返回一個協程對象。協程對象需要註冊到事件循環,由事件循環調用。
-
task 任務:一個協程對象就是一個原生可以掛起的函數,任務則是對協程進一步封裝,其中包含了任務的各種狀態
-
future: 代表將來執行或沒有執行的任務的結果。它和task上沒有本質上的區別
-
async/await 關鍵字:python3.5用於定義協程的關鍵字,async定義一個協程,await用於掛起阻塞的異步調用接口。
import asyncio
import threading
async def wget(host):
print(f'wget {host} ...')
connect = asyncio.open_connection(host, 80)
reader, writer = await connect
header = f'GET / HTTP/1.0\r\nHost: {host}\r\n\r\n'
writer.write(header.encode('utf-8'))
await writer.drain()
while True:
line = await reader.readline()
if line == b'\r\n':
break
print('{host} > {line}'.format(host=host, line=line.decode('utf - 8 ').rstrip()))
writer.close()
loop = asyncio.get_event_loop()
task = [wget(host) for host in ['www.163.com', 'www.sohu.com', 'www.sina.com.cn']]
loop.run_until_complete(asyncio.wait(task))
loop.close()