栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python 协程

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python 协程

1. 多线程、多进程、协程
  • 计算机中提供了:线程、进程 用于实现并发(真实存在)
  • 协程(Coroutine),是程序员通过代码搞出来的东西(非真实存在)
  • 协程也可以被称为微线程,是一种用户态内上下文切换技,其实就是通过一个线程实现代码块相互切换执行
2. Python中有多种方式可以实现协程
  • greenlet
    from greenlet import greenlet
    
    def func1():
    	print(1)
    	gr2.switch()  # 切换到func2函数
    	print(2)
    	gr2.switch()  # 切换到func2函数,从上一次执行的位置继续向后执行
    
    def func2():
    	print(3)
    	gr1.switch()  # 切换
    	print(4)
    
    gr1 = greenlet(func1)
    gr2 = greenlet(func2)
    gr1.switch()  # 去执行func1函数
    
  • yield
    def func1():
    	yield 1
    	yield from func2()
    	yield 2
    
    def func2():
    	yield 3
    	yield 4
    
    f1 = func1()
    for item in f1:
    	print(item)
    
  • 以上两种方法都实现了协程,但无实用意义,来回切换,反倒使程序执行速度更慢
  • 如果使用协程?不要让用户手动切换,而是遇到IO操作时能自动切换
  • Python3.4之后推出了asyncio模块 + Python3.5推出async、async语法,内部基于协程,并且遇到IO请求自动化切换
    import asyncio
    
    async def func1():
    	print(1)
    	await asyncio.sleep(2)
    	print(2)
    
    async def func2():
    	print(3)
    	await asyncio.sleep(2)
    	print(4)
    
    tasks = [
    	asyncio.ensure_future(func1()), 
    	asyncio.ensure_future(func2())
    ]
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait(tasks))
    
    import aiohttp
    import asyncio
    async def fetch(seesion, url):
    	print('发送请求:', url)
    	async with session.get(url, verify_ssl=False) as response:
    		content = await response.content.read()
    		file_name = url.rsplit('_')[-1]
    		with open(file_name, mode='wb') as file_object:
    			file_object.write(content)
    	
    async def main():
    	async with aiohttp.ClientSession() as session:
    		url_list = [
    			'http://www.autoimg.com/....',
    			'http://www.autoimg.com/....',
    			'http://www.autoimg.com/....'
    		]
    		tasks = [asyncio.create_task(fetch(session, url)) for url in url_list]
    		await asyncio.wait(tasks)
    		
    if __name__ = '__main__':
    	asyncio.run(main))
    
  • 在处理IO请求时,协程通过一个线程就可以实现并发操作
3. 协程、线程、进程的区别
  • 线程,是计算机中可以被CPU调度的最小单元
  • 进程,是计算机资源分配的最小单元(进程为线程提供资源)
  • 一个进程中可以有多个线程,同一个进程中的线程可以共享此进程中的资源
  • 由于CPython解释器中GIL的存在:
    • 线程,适用于IO密集型操作
    • 进程,适用于计算密集型操作
  • 协程,也可以被称为微线程,是一种用户态内的上下文切换技术,在开发中结合遇到IO自动切换,就可以通过一个线程实现并发操作
  • 故,在处理IO操作时,协程比线程更加节省开销(协程的开发难度大一些)
  • 支持协程的Python框架:FastAPI、Tornado、Sanic、Django 3、aiohttp等
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/987399.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号