1. 程式人生 > >[python]asyncio介紹以及事件迴圈

[python]asyncio介紹以及事件迴圈

在這裡插入圖片描述

#事件迴圈+回撥(驅動生成器)+epoll(IO多路複用) #asyncio是python用於解決非同步io程式設計的一整套解決方案 #tornado、gevent、twisted(scrapy, django channels) #torando(實現web伺服器), django+flask(uwsgi, gunicorn+nginx) #tornado可以直接部署, nginx+tornado


#使用asyncio

import asyncio
import time
async def get_html(url):
    print("start get url")
    await asyncio.sleep(2)    # 這裡不能使用同步阻塞的方式time.sleep(2),因為這個是單執行緒,會被堵住的。如果啟動的10個會跑20秒
    print("end get url")

if __name__ == "__main__":
    start_time = time.time()
    loop = asyncio.get_event_loop()  #這個相當於select,一個事件迴圈、、可以把asyncio理解為一個協程池

    #loop.run_until_complete(get_html("http://www.imooc.com"))# run_until_complete可以理解為執行緒的join方法,完成後才會向下執行

    tasks = [get_html("http://www.xxx.com") for i in range(10)]
    loop.run_until_complete(asyncio.wait(tasks))

    print(time.time()-start_time)

#獲取協程的返回值

import asyncio
import time
from functools import partial
async def get_html(url):
    print("start get url")
    await asyncio.sleep(2)
    return "bobby"

def callback(url, future):  # 這裡注意future,要放到最後
    print(url)
    print("send email to bobby")

if __name__ == "__main__":
    start_time = time.time()
    loop = asyncio.get_event_loop()
    # get_future = asyncio.ensure_future(get_html("http://www.imooc.com"))  # ensure_future和create_task的效果是一樣的,
    task = loop.create_task(get_html("http://www.imooc.com"))               #都可以獲取協程完成後的return值

    task.add_done_callback(partial(callback, "http://www.imooc.com"))  #add_done_callback,執行完成後,自動呼叫函式
    #add_done_callback,要注意,呼叫函式會預設傳一個future過去。所以callback要加一個引數future,即現在的task
    #如果callback,需要接受多個引數,但add_done_callback只能接受一個callback函式,怎麼解決
    #functools.partial 可以解決這個問題partial(callback, "http://www.imooc.com")
    #相當於callback這個函式帶了一個引數"http://www.imooc.com"


    loop.run_until_complete(task) # run_until_complete這裡的話,可以接收task或者future都OK
    print(task.result()) #和執行緒池一樣,result可以獲取結果return值

#wait 和 gather

import asyncio
import time
async def get_html(url):
    print("start get url")
    await asyncio.sleep(2)
    print("end get url")

if __name__ == "__main__":
    start_time = time.time()
    loop = asyncio.get_event_loop()
    tasks = [get_html("http://www.imooc.com") for i in range(10)]
    #loop.run_until_complete(asyncio.wait(tasks))
    # loop.run_until_complete(asyncio.gather(*tasks))
    # print(time.time()-start_time)

    #gather和wait的區別
    #gather更加high-level
    group1 = [get_html("http://projectsedu.com") for i in range(2)]
    group2 = [get_html("http://www.imooc.com") for i in range(2)]
    #loop.run_until_complete(asyncio.gather(*group1, *group2))
    group1 = asyncio.gather(*group1)
    group2 = asyncio.gather(*group2)
    group2.cancel() #取消分組
    loop.run_until_complete(asyncio.gather(group1, group2))
    print(time.time() - start_time)