1. 乙個爬蟲的例子
import time
def crawl_page(url):
print('crawling {}'.format(url))
sleep_time = int(url.split('_')[-1])
time.sleep(sleep_time)
print('ok {}'.format(url))
def main(urls):
for url in urls:
crawl_page(url)
%time main(['url_1', 'url_2', 'url_3', 'url_4'])
########## 輸出 ##########
crawling url_1
ok url_1
crawling url_2
ok url_2
crawling url_3
ok url_3
crawling url_4
ok url_4
wall time: 10 s
scrawl_page 為函式休眠數秒,休眠時間取決於url最後的那個數字。
main()函式執行,調取craw_page()函式進行網路通訊,經過若干秒等待後收到結果,然後執行下乙個。
它也占用了不少時間,五個頁面分別用了1秒到4秒的時間 ,加起來一共用了10秒,這樣效率低,所以要優化,乙個簡單的思路就是併發化,用協程來寫。
import asyncio
async def crawl_page(url):
print('crawling {}'.format(url))
sleep_time = int(url.split('_')[-1])
await asyncio.sleep(sleep_time)
print('ok {}'.format(url))
async def main(urls):
for url in urls:
await crawl_page(url)
%time asyncio.run(main(['url_1', 'url_2', 'url_3', 'url_4']))
########## 輸出 ##########
crawling url_1
ok url_1
crawling url_2
ok url_2
crawling url_3
ok url_3
crawling url_4
ok url_4
wall time: 10 s
import asyncio這個庫包含了大部分我們實現協程所需的魔法工具
async修飾詞宣告非同步函式,於是這裡的craw_page和main都變成了非同步函式,而呼叫非同步函式,我們便可得到乙個協程物件(coroutine object).
執行協程有多個方法,常用的三種:
await執行的效果,和python正常執行一樣的,也就是說程式會阻塞在這,進入被呼叫的協程函式,執行完畢後再繼續,而這也是await的字面意思,**中await asynio.sleep(sleep_time)會在這裡休息若干秒,await crawl_page(url)則會執行craw_page()函式。
asyncio.create_task()來建立任務,最後用asynicio.run來執行。
import asyncio
async def crawl_page(url):
print('crawling {}'.format(url))
sleep_time = int(url.split('_')[-1])
await asyncio.sleep(sleep_time)
print('ok {}'.format(url))
async def main(urls):
tasks = [asyncio.create_task(crawl_page(url)) for url in urls]
for task in tasks:
await task
%time asyncio.run(main(['url_1', 'url_2', 'url_3', 'url_4']))
########## 輸出 ##########
crawling url_1
crawling url_2
crawling url_3
crawling url_4
ok url_1
ok url_2
ok url_3
ok url_4
wall time: 3.99 s
python協程與非同步協程
在前面幾個部落格中我們一一對應解決了消費者消費的速度跟不上生產者,浪費我們大量的時間去等待的問題,在這裡,針對業務邏輯比較耗時間的問題,我們還有除了多程序之外更優的解決方式,那就是協程和非同步協程。在引入這個概念之前我們先看 看這個圖 從這個我們可以看出來,假如來了9個任務,即使我們開了多程序,在業...
python協程使用 協程的案例
概念 使用者層面在乙個執行緒中進行多工切換的機制,比執行緒更加輕量級 實現併發量更大 協程的使用 使用第三方庫 gevent gevent 是乙個基於協程的 python 網路庫,在遇到 io 阻塞時,程式會自動進行切換,可以讓我們用同步的放肆寫非同步 io 協程的使用 from gevent im...
python 併發程式設計 協程 協程介紹
協程 是單執行緒下的併發,又稱微執行緒,纖程。英文名coroutine。一句話說明什麼是執行緒 協程是一種使用者態的輕量級執行緒,即協程是由使用者程式自己控制排程的 需要強調的是 1.python的執行緒屬於核心級別的,即由作業系統控制排程 如單執行緒遇到io或執行時間過長就會被迫交出cpu執行許可...