[python]asyncio介绍以及事件循环-LMLPHP

#事件循环+回调(驱动生成器)+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)
10-03 14:54