python asyncio 异步编程---协程

1、协程

官方描述;
协程是子例程的更一般形式。 子例程可以在某一点进入并在另一点退出。 协程则可以在许多不同的点上进入、退出和恢复。 它们可通过 async def 语句来实现。 参见 PEP 492。

  • 协程不是计算机内部提供的,不像进程、线程,由电脑本身提供,它是由程序员人为创造的, 实现函数异步执行。

  • 协程(Coroutine),也可以被称为微线程,是一种用户太内的上下文切换技术,其实就是通过一个线程实现代码块相互切换执行。看上去像子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。例如:

# 需要python3.7+
import asyncioasync def main():print('hello')await asyncio.sleep(1)print('world')asyncio.run(main())# 打印 "hello",等待 1 秒,再打印 "world"

注意:简单地调用一个协程并不会使其被调度执行,

直接main() 调用会有问题:

RuntimeWarning: coroutine 'main' was never awaitedmain()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

def func1():print(1)...print(2)def func2():print(3)...print(4)func1()
func2() # 结果:1 2 3 4

实现协程的方法:

  • greenlet,早期模块【不建议使用】
  • yield关键字,它是python的生成器,具有保存状态,切换到其他函数去执行,再切换回原函数的功能。
  • asyncio装饰器(python3.4引入)
  • async、await 关键字(python3.5)【推荐使用】

1.1 greenlet实现协程

# 第三方模块,因此需要安装pip install greenlet
from greenlet import greenletdef func1():print(1)gr2.switch()print(2)gr2.switch()def func2():print(3)gr1.switch()print(4)gr1 = greenlet(func1)
gr2 = greenlet(func2)gr1.switch()# 结果:1 3 2 4

1.2 yield关键字

def func1():yield 1yield from func2()yield 2def func2():yield 3yield 4f1 = func1()
for item in f1:print(item)# 结果:1 3 2 4

1.3 asynico装饰器

python3.4 及之后版本支持

DeprecationWarning: “@coroutine” decorator is deprecated since Python 3.8, use “async def”
翻译:@coroutine"装饰器自Python 3.8起已弃用,请使用"async def"代替

所以这个也不支持。

import asyncio@asyncio.coroutine
def func1():print(1)yield from asyncio.sleep(2)  # 遇到IO耗时操作,自动切换到tasks中其他任务,比如:网络IO,下载图片print(2)@asyncio.coroutine
def func2():print(3)yield from asyncio.sleep(2)  # 遇到IO耗时操作,自动切换到tasks中其他任务,比如:网络IO,下载图片print(4)tasks = [asyncio.ensure_future(func1()),asyncio.ensure_future(func2())
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))# 结果: 1 3 2 4

1.4 async & await 关键字

import asyncioasync def func1():print(1)await asyncio.sleep(2)  # 遇到IO耗时操作,自动切换到tasks中其他任务,比如:网络IO,下载图片print(2)async def func2():print(3)await asyncio.sleep(2)  # 遇到IO耗时操作,自动切换到tasks中其他任务,比如:网络IO,下载图片print(4)tasks = [asyncio.ensure_future(func1()),asyncio.ensure_future(func2())
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

2. 协程的意义

充分利用线程。在一个线程中如果遇到IO等待时间线程不会一直等待,利用空闲时间再去干点其他事情。

以下载三张图片为例:

  • 普通方式(同步)下载:
import time
import requestsdef download_image(url, img_name):print("开始下载:", url)# 发送网络请求,下载图片response = requests.get(url)print("下载完成")# 图片保存到本地文件file_name = str(img_name) + '.png'with open(file_name, mode='wb') as file:file.write(response.content)if __name__ == '__main__':start = time.time()url_list = ['https://tse4-mm.cn.bing.net/th/id/OIP.866vRxQ8QvyDsrUuXiu7qwHaNK?w=182&h=324&c=7&o=5&pid=1.7','https://tse2-mm.cn.bing.net/th/id/OIP.HUcWtoYPG-z2pu4ityajbAHaKQ?w=182&h=252&c=7&o=5&pid=1.7','https://tse2-mm.cn.bing.net/th/id/OIP.MvncR0-Pt9hVxKTdrvD9dAHaNK?w=182&h=324&c=7&o=5&pid=1.7','https://tse1-mm.cn.bing.net/th/id/OIP._nGloaeMWbL7NB7Lp6SnXQHaLH?w=182&h=273&c=7&o=5&pid=1.7',]img_name = 1for item in url_list:download_image(item, img_name)img_name += 1end = time.time()print(end - start)# 最终时间:7.25s
  • 协程方式(异步)下载:
import aiohttp
import asyncio
import timeasync def fetch(session, url):print("发送请求:", url)async with session.get(url, verify_ssl=False) as response:content = await response.content.read()file_name = url.rsplit('_')[-1]# print(file_name)with open(file_name, mode='wb') as file_object:file_object.write(content)print("下载完成")async def main():async with aiohttp.ClientSession() as session:url_list = ['https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg','https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg','https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg','https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg',]tasks = [asyncio.ensure_future(fetch(session, url)) for url in url_list]await asyncio.wait(tasks)if __name__ == '__main__':start = time.time()asyncio.get_event_loop().run_until_complete(main())end = time.time()print(end - start)# 结果:0.05s

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/491927.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二十大未来最有潜力的新材料(绝对经典值得收藏)

来源:新材料在线石墨烯、碳纳米管、非晶合金、泡沫金属、离子液体……20种新材料,为材料工业工业发展带来无限机遇。材料工业是国民经济的基础产业,新材料是材料工业发展的先导,是重要的战略性新兴产业。今天,科技革命…

Unity3D 4.x 使用Mecanim实现动画控制

Unity3D 4.x 版本号之后提供了一种新的动画机制Mecanim,尽管眼下还支持之前的Animation。但看到Unity3D 4.3 预览版里Sprite的动画也是基于Animator的,可知Mecanim将会是以后动画播放的趋势! Mecanim是一种基于状态机的结构,不同的…

全国国家重点实验室分布总览

来源:114产学研在我国的科研平台,企业国家重点实验室、国家重点实验室和省部共建国家重点实验室在科学前沿探索和解决国家重大需求方面发挥了非常重要的作用,在科学研究方面取得不少具有国际先进水平的成果。2018年5月21日,科技部…

(算法)宝石升级问题

题目: 有一块宝石,1级升2级成功率100%,2级升3级成功率80%,3级升4级成功率60%,4级升5级成功率40%,每次升级失败时降回到1级。请问一块1级宝石升到5级平均要多少…

python asyncio 异步编程-协程 2

asyncio 异步编程 官方文档: 中文版:https://docs.python.org/zh-cn/3.8/library/asyncio.html英文本:https://docs.python.org/3.8/library/asyncio.html 1. 事件循环 事件循环 是指主线程每次将执行序列中的任务清空后,就去…

能源枯竭?在能源互联网时代不存在!

曹军威清华大学信息技术研究院研究员、副院长北京智中能源互联网研究院首席科学家来源:DeepTech深科技演绎inSite第十一期节目能量路由器离我们还远吗?曹军威演绎inSite演讲视频链接:以下为曹军威老师演讲文字稿:(根据…

Django3 --- ASGI

1. 什么是WSGI 1.1 CGI 解释 WSGI 之前应该先说一下什么是 CGI(通用网关接口,Common Gateway Interface,CGI),是Web 服务器运行时外部程序的规范 , 是外部扩展应用程序与 Web 服务器交互的一个标准接口。…

itextsharp c# asp.net 生成 pdf 文件

一切的开始必须要有2个dll, 可以通过nuget 包xiazai, 关键字是itextsharp. using iTextSharp.text; using iTextSharp.text.pdf; FileStream fs new FileStream(Server.MapPath("pdf") "\\" "First PDF document6.pdf"…

网络安全:等保2.0落地在即,触发五百亿新增市场

报告数据来源:华创证券、东方财富、东吴证券前 言:据公安部十一局七处处长祝国邦:《网络安全等级保护技术》2.0版本将于5月13日发布。相比等保1.0只针对网络和信息系统,等保2.0把云计算、大数据、物联网等新业态也纳入了监管&…

Django3 --- async

官方文档:https://docs.djangoproject.com/en/3.2/releases/3.0/ Django 3.0 通过提供对作为ASGI应用程序运行的支持,开始了我们使 Django 完全具有异步能力的旅程。 Django 3.1于2020年8月4日发布!从3.1版本开始,Django将逐步原…

产业|一文读懂自动驾驶汽车产业链上下游

来源: 亿欧自动驾驶汽车它的产业链上下游已经出现支撑公司,并在逐渐走向成熟。自动驾驶分级标准 关于自动驾驶的分级,主要有SAE(美国机动车工程师学会)标准和NHTSA(国家公路交通安全管理局)两个…

【python asyncio 运行报错】:raise RuntimeError(‘There is no current event loop in thread %r‘)

代码: # 执行第一个协程程序 asyncio.run(S.crawl_url())select_date S.select_date() select_keyword S.select_keyword(select_date) # 列表# 第二个协程 loop asyncio.get_event_loop() loop.run_until_complete(asyncio.wait([S.parse_html(url) for url i…

Repository 返回 IQueryable?还是 IEnumerable?

这是一个很有意思的问题,我们一步一步来探讨,首先需要明确两个概念(来自 MSDN): IQueryable:提供对未指定数据类型的特定数据源的查询进行计算的功能。IEnumerable:公开枚举数,该枚举…

AI教父杰弗里辛顿:AI反学习可能揭开人类梦境的奥秘

来源:网易智能近日,多伦多大学的教员、谷歌大脑(Google Brain)研究员杰弗里辛顿(Geoffrey Hinton)发表了炉边谈话。他讨论了神经网络的起源,以及人工智能有朝一日可能像人类一样推理的可行性和意…

AttributeError: partially initialized module ‘aiohttp‘ has no attribute ‘ClientSession‘ (most...)

AttributeError: partially initialized module ‘aiohttp’ has no attribute ‘ClientSession’ (most likely due to a circular import) 问题描述: AttributeError: partially initialized module ‘aiohttp’ has no attribute ‘ClientSession’ (most likely…

关于线程池ThreadPoolExecutor使用总结

本文引用自: http://blog.chinaunix.net/uid-20577907-id-3519578.html 一、简介 线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为: ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit uni…

AIoT重磅报告:四大关键助力,AI+IoT重新定义未来的可能性

来源:北京物联网智能技术应用协会,智能巅峰导 读随着科技的不断发展,一些在功能上具有相互补充作用的技术正在不可避免地发生结合——例如,人工智能(AI)和物联网(IoT)。在本文中,我…

python---aiohttp库

python—aiohttp库 1. 什么事aiohttp 官方网址:https://docs.aiohttp.org/en/stable/ 用于asyncio和Python的异步HTTP客户端/服务器 2. 安装 pip install aiohttp3. ClientSession() Session封装了一个连接池(connector instance)&…

关于机器学习实战,那些教科书里学不到的12个“民间智慧”

来源:towardsml机器学习算法被认为能够通过学习数据来弄清楚如何执行重要任务。这意味着数据量越大,这些算法就可以解决更加复杂的问题。然而,开发成功的机器学习应用程序需要一定的“民间技巧”,这在教科书或机器学习入门课程中很…

asp.net winform 实现复制,粘贴,剪切功能

System.Windows.Forms.SendKeys.SendWait("^C");//复制System.Windows.Forms.SendKeys.SendWait("^V");//粘贴 System.Windows.Forms.SendKeys.SendWait("^X");//剪切转载于:https://www.cnblogs.com/ninestart/p/4760801.html