天天看點

02-12 單線程+多任務異步協程

一、 理論基礎

1、線程是有限的,線程開啟過多,CPU吃不消

2、多任務--理論上每個線程下可以開啟很多協程,但實際效果一般
500個最佳,速度最快
           

‘’’

二、爬蟲推薦單線程+多任務異步協程

1、協程

是一個對象,可以吧協程當做衣蛾特殊的函數,如果一個函數的
定義被async關鍵字修飾,該特殊的函數被調用後函數内部的程式語
句不會被立即執行,而是會傳回一個協程對象,如eg1
           

2、任務對象(task):

所謂的任務對象就是協程對象的進一步封裝
( 即是一個進階的協程對象)
在任務對象中可以實作顯示協程對象的運作狀況
    -任務對象需要被注冊到時間循環對象中
    -核心:綁定回調
        -回調函數綁定給任務隊象,隻有當任務隊象的特殊函數執行完
  畢後,回調函數才會被執行
           

3、事件循環對象

無限循環的對象(可以将其了解為一中容器,該容器中需要放置多
個任務對象)就是一組待執行的任務
    -無線循環:指所有的任務因為阻塞可能執行無數次,不是指含
有無限個任務
    -異步的提現:當事件循環開啟後,該對象就會按照順序執行每
一個任務對象
           

4、await

挂起的操作-可了解為交出CPU的使用權,(程序和線程中
 系統會對阻塞的任務自動挂起),但在協程中,需手動進行
 挂起操作
           

main_program:

from time import sleep
import asyncio

# 回調函數,其預設參數為任務隊象
def call_back(task):
    print('i am callback!!!','開始執行我了')
    print(task.result()) #這裡的傳回值就是任務隊象中那個特殊的函數的傳回值

async def get_request(url):
    print('現在請求:',url)
    sleep(2)
    print('請求結束了!!',url)
    return 'xinixn'

           

eg1:協程對象

#建立一個協程對象
c=get_request('www.huhu.com')
print(c)

傳回為一個協程對象:<coroutine object get_request
 at 0x00000000021A6EC0>
           

eg2: 任務對象與事件循環對象的使用

#封裝一個任務對象
task=asyncio.ensure_future(c)

# 給任務對象綁定回調函數
task.add_done_callback(callback)


# 建立一個事件循環對象
loop=asyncio.get_event_loop()

loop.run_until_complete(task) 
#将任務對象注冊到事件循環對象中并且開啟了事件循環
           

應用場景總結:

1、爬蟲中,爬取響應和資料解析和兩個過程,必須分先後進行(即隻能能串行),是以上述

任務對象: 可封裝爬取部分
回調函數:封裝解析資料部分
           

2、任務對象就是:

封裝的待執行的特殊代碼塊
           

3、事件循環對象中

預設有一個事件執行情況監控機制,運作過程中某個事件發生了阻
塞,就會自動切換另外任務執行,進而實作異步
           

繼續閱讀