[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值
#注册协程到loop中有两种方法ensure_future/create_task
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)