python异步编程框架asyncio
生活随笔
收集整理的這篇文章主要介紹了
python异步编程框架asyncio
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
并行和并發
- 并行:在操作系統中是指,一組程序按獨立異步的速度執行,無論從微觀還是宏觀,程序都是一起執行的。
- 并發:在操作系統中,是指一個時間段中有多個已啟動的程序運行在同一個執行機上,多個程序交替著切換執行,但任一個時刻點上只有一個程序在處理機上運行。宏觀上給人并行的表現,微觀上仍是順序執行
阻塞非阻塞
- 阻塞和非阻塞指的是調用者(程序)在等待返回結果(或輸入)時的狀態。
- 阻塞:在調用結果返回前,當前線程會被掛起,并在得到結果之后返回。
- 非阻塞:如果不能立刻得到結果,則該調用者當前線程還可以先干些別的事兒,不會阻塞當前線程,同時調用者需要定時輪詢查看處理狀態。
同步/異步
- 同步:在發出一個同步調用時,在沒有得到結果之前,該調用就不返回。
- 異步:在發出一個異步調用后,調用者不會立刻得到結果,該調用就返回了
簡單使用
# python 源碼 import asyncio import timeasync def task(task_name):print(task_name, 'start')await asyncio.sleep(5)print(task_name, 'end')return task_nameasync def main():print('task_main', 'start')# 創建兩個任務,等待運行task1 = task("task_01")task2 = task("task_02")a = await task1b = await task2print(a, b)print('task_main', 'end')if __name__ == '__main__':t = time.time()# 方式一loop = asyncio.get_event_loop() # 創建事件循環loop.run_until_complete(main()) # 添加任務,直至所有任務執行完成loop.close() # 關閉事件循環,事件循環關閉后,再次調用loop,將不會再次執行# 方式二,python3.7省略的手動創建事件循環,可直接用asyncio.run()去執行協程任務。asyncio.run(main())print('總耗時:', time.time() - t)上面例子task1和task2都是異步執行,但需要等待執行結果才能執行下一個任務,因此task1和task2將會是順序執行,如果想并發執行則需要采用asyncio.create_task()聲明為異步任務,先統一執行,后統一等待結果
創建異步任務
修改main函數
asyncio: Task, create_task, ensure_future 都可以創建任務,該用哪個?
執行過程分析
import asyncio import timeasync def task(task_name):print(task_name, 'start')await asyncio.sleep(5)print(task_name, 'end')return task_nameasync def main():print('task_main', 'start')# 創建四個任務,等待運行task1 = asyncio.create_task(task("task_01"))task2 = asyncio.create_task(task("task_02"))# 休眠5秒鐘,可以看到四個任務沒有打印輸出# 那是因為time.sleep是阻塞的,由于只有一個線程,而此時線程正在被休眠獨自占用,沒有io等耗時任務,不會發生協程切換print('線程休眠開始')time.sleep(5)print('線程休眠結束,協程有機會或則執行權')# time.sleep執行結束,線程不再被阻塞,四個task有機會得到執行,因為四個task內部有耗時任務(阻塞),因此會協程會相互切換,達到類似并行的效果,本質還是并發# 等待協程task執行完畢,主線程在結束# 1. 給足夠的時間讓task執行完畢,否則協程還沒執行完畢,主線程就已經結束了await asyncio.sleep(5)# 2. 或者分別等待每個task結束,類似多線程中task.join()print('task_main', 'running')a = await task1b = await task2print(a, b)print('task_main', 'end')if __name__ == '__main__':t = time.time()asyncio.run(main())print('總耗時:', time.time() - t)asyncio.gather 用法
返回的是所有已完成 Task 的 result,不需要再進行調用或其他操作,就可以得到全部結果
最常見的用法是:await asyncio.gather(*task_list),注意這里 task_list 前面有一個 *。
不用create_task也一樣
async def main():print('task_main', 'start')# 創建兩個任務,等待運行results = await asyncio.gather(*[task("task_01"), task("task_02")])print(results)print('task_main', 'end')asyncio.wait 用法
asyncio.wait 會返回兩個值:done(已完成的協程task) 和 pending(超時未完成的協程task),需通過 future.result()獲取返回值。
最常見的寫法是:await asyncio.wait(task_list),修改main函數
總結
以上是生活随笔為你收集整理的python异步编程框架asyncio的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Turbo Boost
- 下一篇: websocket python爬虫_p